API-Referenz
Authentifizieren Sie sich und fragen Sie die Hiring-API nach Stellenanzeigen, Kandidaten und Bewerbungen ab.
Warum es wichtig ist
Die Hiring-API gibt externen Systemen Lesezugriff auf Ihre Einstellungsdaten — Jobbörsen rufen veröffentlichte Stellenanzeigen ab, HRIS-Systeme synchronisieren Kandidatendatensätze, Dashboards verfolgen Pipeline-Metriken. Token-Scopes stellen sicher, dass jede Integration nur das sieht, was sie benötigt.
Basis-URL
Alle API-Endpunkte sind erreichbar über:
https://startupkit.app/api/v1
Ersetzen Sie startupkit.app durch Ihre tatsächliche Kit-Domain.
Authentifizierung
Jede Anfrage erfordert ein API-Token im Authorization-Header:
Authorization: Bearer YOUR_TOKEN
Alternatives Format (beide funktionieren):
Authorization: token YOUR_TOKEN
Erstellen Sie Tokens unter Einstellungen > API. Jedes Token muss explizite Scopes haben, um auf Hiring-Endpunkte zugreifen zu können.
| Scope | Zugriff |
|---|---|
job_postings:read |
Stellenanzeigen und Phasen |
candidates:read |
Personenbezogene Kandidatendaten (Name, E-Mail, Telefon), Lebenslauf-Downloads |
applications:read |
Bewerbungen, Phasenverlauf, Lebenslauf-Downloads |
Tokens ohne Scopes können nicht auf Hiring-Endpunkte zugreifen.
Token-Format und Lebenszyklus
- Format: 32-stelliger hexadezimaler String (z. B.
a1b2c3d4e5f6...) - Nachverfolgung der letzten Nutzung: Jede erfolgreiche Anfrage aktualisiert
last_used_at - Ablauf: Optional kann beim Erstellen des Tokens ein
expires_atfestgelegt werden - Inaktivitätswarnungen: Tokens, die länger als 30 Tage nicht verwendet wurden, lösen Admin-Benachrichtigungen aus
- Automatischer Widerruf: Tokens werden automatisch widerrufen, wenn ein Benutzer aus dem Konto entfernt wird
Best Practice: Erstellen Sie separate Tokens pro Integration mit den minimal erforderlichen Scopes.
Kontozuordnung
Jedes API-Token ist an ein bestimmtes Konto gebunden. Das Konto wird automatisch aus dem Token abgeleitet — es ist kein account_id-Parameter erforderlich.
Wenn ein Teammitglied aus einem Konto entfernt wird, werden dessen Tokens für dieses Konto automatisch widerrufen.
Fehlerantworten
| Status | Bedeutung | Häufige Ursachen |
|---|---|---|
400 |
Fehlerhafte Anfrage | Kontokontext fehlt (Sonderfall bei sitzungsbasierter Authentifizierung) |
401 |
Nicht autorisiert | Fehlendes, ungültiges oder abgelaufenes Token |
403 |
Verboten | Token hat nicht den erforderlichen Scope für diesen Endpunkt |
404 |
Nicht gefunden | Ressource existiert nicht oder gehört nicht zu Ihrem Konto |
422 |
Nicht verarbeitbar | Validierungsfehler (hauptsächlich für Nicht-Hiring-Endpunkte) |
Paginierung
Listen-Endpunkte geben paginierte Ergebnisse zurück:
{
"data": [...],
"pagination": {
"current_page": 1,
"total_pages": 3,
"total_count": 42,
"per_page": 20
}
}
Übergeben Sie ?page=2, um nachfolgende Seiten abzurufen.
Stellenanzeigen
Erforderlicher Scope: job_postings:read
Stellenanzeigen auflisten
GET /api/v1/job_postings
Beispiel:
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://startupkit.app/api/v1/job_postings?status=published
Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
status |
string | Filtern nach draft, published oder closed |
page |
integer | Seitennummer |
Antwort:
{
"data": [
{
"id": "job_abc123",
"title": "Senior Rails Developer",
"status": "published",
"department": "Engineering",
"location": "New York, NY",
"employment_type": "full_time",
"remote": true,
"salary_min": "120000.0",
"salary_max": "180000.0",
"salary_currency": "USD",
"salary_period": "year",
"published_at": "2026-01-15T10:00:00Z",
"closed_at": null,
"created_at": "2026-01-10T08:30:00Z",
"updated_at": "2026-02-01T14:20:00Z",
"stages": [
{
"id": "stg_def456",
"name": "Screening",
"stage_type": "default",
"position": 0
}
],
"counts": {
"total_applications": 24,
"active_applications": 18,
"rejected": 6
}
}
],
"pagination": { ... }
}
Stellenanzeige abrufen
GET /api/v1/job_postings/:id
Gibt die gleiche Struktur wie ein Element in der Listenantwort zurück.
Phasen auflisten
GET /api/v1/job_postings/:job_posting_id/stages
Antwort:
{
"data": [
{
"id": "stg_def456",
"name": "Screening",
"stage_type": "default",
"position": 0
}
]
}
Phasen sind nach Position sortiert. Keine Paginierung.
Kandidaten
Erforderlicher Scope: candidates:read
Kandidaten auflisten
GET /api/v1/candidates
Beispiel:
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://startupkit.app/api/v1/[email protected]
Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
search |
string | Suche nach Name oder E-Mail |
page |
integer | Seitennummer |
Antwort:
{
"data": [
{
"id": "cand_ghi789",
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]",
"phone": "+1-555-0100",
"status": "active",
"github_username": "johndoe",
"created_at": "2026-01-20T09:15:00Z",
"applications": [
{
"id": "app_jkl012",
"job_posting_id": "job_abc123",
"job_posting_title": "Senior Rails Developer",
"current_stage_name": "Interview",
"status": "active",
"submitted_at": "2026-01-20T09:15:00Z"
}
]
}
],
"pagination": { ... }
}
Kandidat abrufen
GET /api/v1/candidates/:id
Gibt die gleiche Struktur wie ein Element in der Listenantwort zurück.
Bewerbungen
Erforderlicher Scope: applications:read
Bewerbungen auflisten
GET /api/v1/applications
Beispiel:
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://startupkit.app/api/v1/applications?job_posting_id=job_abc123&status=active
Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
job_posting_id |
string | Filtern nach Stellenanzeigen-Präfix-ID |
status |
string | Filtern nach active oder rejected |
page |
integer | Seitennummer |
Antwort:
{
"data": [
{
"id": "app_jkl012",
"job_posting_id": "job_abc123",
"candidate_id": "cand_ghi789",
"current_stage_name": "Interview",
"status": "active",
"submitted_at": "2026-01-20T09:15:00Z",
"created_at": "2026-01-20T09:15:00Z",
"updated_at": "2026-02-10T11:30:00Z",
"candidate": {
"id": "cand_ghi789",
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]"
},
"stage_history": [
{
"id": "sp_mno345",
"stage_name": "Screening",
"stage_type": "default",
"status": "completed",
"started_at": "2026-01-20T09:15:00Z",
"completed_at": "2026-01-25T16:00:00Z"
},
{
"id": "sp_pqr678",
"stage_name": "Interview",
"stage_type": "interview",
"status": "in_progress",
"started_at": "2026-01-25T16:00:00Z",
"completed_at": null
}
]
}
],
"pagination": { ... }
}
Bewerbung abrufen
GET /api/v1/applications/:id
Gibt die gleiche Struktur wie ein Element in der Listenantwort zurück. Wenn das Token den Scope candidates:read besitzt und der Bewerbung ein Lebenslauf beigefügt ist, enthält die Antwort Lebenslauf-Metadaten:
{
"id": "app_jkl012",
"resume_filename": "john_doe_resume.pdf",
"resume_content_type": "application/pdf",
"resume_byte_size": 245760,
...
}
Diese Felder werden ausgelassen, wenn kein Lebenslauf angehängt ist oder der Scope candidates:read fehlt.
Lebenslauf herunterladen
Erforderliche Scopes: applications:read + candidates:read
GET /api/v1/applications/:application_id/resume
Lädt den Lebenslauf des Kandidaten für die angegebene Bewerbung herunter. Gibt eine 302-Weiterleitung zu einer zeitlich begrenzten signierten URL zurück (gültig für 30 Minuten).
Beispiel:
curl -L -H "Authorization: Bearer YOUR_TOKEN" \
-o resume.pdf \
https://startupkit.app/api/v1/applications/app_jkl012/resume
Antwort:
302 Found– Weiterleitung zur signierten Download-URL. Verwenden Sie-L(Weiterleitungen folgen) mit curl.403 Forbidden– Token hat nicht den Scopeapplications:readodercandidates:read.404 Not Found– Bewerbung nicht gefunden oder kein Lebenslauf angehängt.
Hinweise:
- Signierte URLs laufen nach 30 Minuten ab. Bei Ablauf fordern Sie eine neue an.
- Der
Content-Disposition-Header ist aufattachmentgesetzt (löst einen Browser-Download aus). - Lebenslauf-Dateitypen: PDF, DOC, DOCX (wie vom Kandidaten hochgeladen).
Schwärzung personenbezogener Kandidatendaten
Wenn ein Token applications:read hat, aber nicht candidates:read, werden die Kandidatendaten in Bewerbungsantworten auf die ID reduziert:
{
"candidate": {
"id": "cand_ghi789"
}
}
Die Felder first_name, last_name und email werden nicht einbezogen. Dies ermöglicht es Jobbörsen-Integrationen, den Bewerbungsstatus zu verfolgen, ohne Kontaktinformationen der Kandidaten offenzulegen.
Fehlerbehebung
Authentifizierungsprobleme
401 Unauthorized
Wenn Sie eine 401-Antwort erhalten, prüfen Sie:
- Token-Format: Stellen Sie sicher, dass das Token genau so ist, wie es unter Einstellungen > API angezeigt wird (32-stelliger Hex-String)
- Authorization-Header: Muss
Authorization: Bearer TOKENoderAuthorization: token TOKENsein - Token-Ablauf: Prüfen Sie unter Einstellungen > API, ob
expires_atüberschritten wurde - Kontomitgliedschaft: Stellen Sie sicher, dass der Token-Inhaber noch Mitglied des Kontos ist
403 Forbidden
Wenn Sie eine 403-Antwort erhalten, ist das Token gültig, hat aber nicht den erforderlichen Scope:
- Erforderliche Scopes prüfen: Jeder Endpunkt dokumentiert seinen erforderlichen Scope (z. B.
job_postings:read) - Fehlende Scopes hinzufügen: Bearbeiten Sie das Token unter Einstellungen > API und fügen Sie den benötigten Scope hinzu
- Scope-Format: Muss exakt übereinstimmen —
job_postings:read, nichtjob_postingsoderread
Datenzugriffsprobleme
Leeres data-Array in Antworten
Wenn die API {"data": [], "pagination": {...}} zurückgibt, Sie aber Ergebnisse erwarten:
- Kontoisolation: API-Tokens sehen nur Daten ihres zugeordneten Kontos
- Konto überprüfen: Prüfen Sie unter Einstellungen > API, zu welchem Konto das Token gehört
- Kontoübergreifender Zugriff: Tokens können nicht auf Daten anderer Konten zugreifen, selbst wenn der Benutzer Mitglied ist
Kandidaten-PII ist geschwärzt
Wenn Sie nur {"candidate": {"id": "cand_..."}} ohne Name oder E-Mail sehen:
- Erwartetes Verhalten: Dies geschieht, wenn das Token
applications:readhat, aber nichtcandidates:read - Scope hinzufügen: Um vollständige Kandidatendetails zu sehen, fügen Sie den Scope
candidates:readzu Ihrem Token hinzu - Privacy by Design: Dies ermöglicht Integrationen, Bewerbungen zu verfolgen, ohne Kontaktinformationen offenzulegen
Abfrage- und Filterprobleme
404 beim Abrufen bestimmter Datensätze
- Präfix-IDs verwenden: Stellenanzeigen verwenden das Format
job_abc123, nicht Datenbank-IDs wie42 - Groß-/Kleinschreibung: Präfix-IDs unterscheiden zwischen Groß- und Kleinschreibung
- Kontozuordnung: Die Ressource muss zum Konto des Tokens gehören
Filterparameter funktionieren nicht
- Gültige Statuswerte:
- Stellenanzeigen:
draft,published,closed(Groß-/Kleinschreibung beachten) - Bewerbungen:
active,rejected(Groß-/Kleinschreibung beachten)
- Stellenanzeigen:
- Parameterformat: Verwenden Sie
?status=published, nicht?status=Publishedoder?filter[status]=published
Häufig gestellte Fragen
Wie funktioniert die Paginierung?
Alle Listen-Endpunkte geben 20 Einträge pro Seite zurück (fest). Verwenden Sie ?page=2 für die nächste Seite. Das pagination-Objekt zeigt total_pages und total_count.
Laufen Tokens automatisch ab?
Nur wenn Sie beim Erstellen des Tokens ein expires_at festgelegt haben. Andernfalls bleiben Tokens gültig, bis:
- Sie manuell unter Einstellungen > API widerrufen werden
- Der Benutzer aus dem Konto entfernt wird
- Das Konto gelöscht wird
Sollte ich ein Token für mehrere Integrationen verwenden?
Nein. Best Practice ist ein Token pro Integration mit minimalen Scopes. Dies erleichtert:
- Die Überprüfung, welche Integration Anfragen stellt (über
last_used_at) - Den Widerruf des Zugriffs für eine bestimmte Integration, ohne andere zu beeinträchtigen
- Die Vergabe unterschiedlicher Berechtigungen an verschiedene Systeme
Wie hängen Webhooks mit der API zusammen?
Webhooks benachrichtigen Sie über Ereignisse (neue Bewerbung, Phasenwechsel). Die API ermöglicht die Abfrage des aktuellen Zustands. Verwenden Sie Webhooks, um Ihr System auszulösen, und dann die API, um vollständige Details abzurufen.
Kann ich mehr als 20 Einträge pro Seite erhalten?
Nein. Die Seitengröße ist auf 20 Einträge festgelegt, um eine konsistente Leistung zu gewährleisten. Verwenden Sie den page-Parameter, um alle Ergebnisse zu durchlaufen.
Kurz-Checkliste
- Erstellen Sie ein API-Token unter Einstellungen > API — jedes Token ist an dieses Konto gebunden
- Weisen Sie nur die Scopes zu, die Ihre Integration benötigt (Best Practice: ein Token pro Integration mit minimalen Scopes)
- Prüfen Sie
expires_atunter Einstellungen > API, um zu sehen, wann das Token abläuft (falls festgelegt) - Fügen Sie
Authorization: Bearer TOKENbei jeder Anfrage hinzu - Verwenden Sie Präfix-IDs (z. B.
job_abc123) in URLs, nicht Datenbank-IDs - Behandeln Sie
400- und422-Antworten für Validierungsfehler - Behandeln Sie
401-Antworten — Ihr Token könnte abgelaufen oder widerrufen sein - Behandeln Sie
403-Antworten — Ihrem Token könnte ein erforderlicher Scope fehlen - Verwenden Sie den
page-Parameter, um große Ergebnismengen zu paginieren (20 Einträge pro Seite)