Logo StartupKit
DE

Public Jobs API

Bauen Sie Ihre eigene Jobseite (z. B. mit Next.js auf Vercel) auf Ihrer Kit-Hiring-Pipeline auf. Listen Sie veröffentlichte Stellen auf und empfangen Sie Bewerbungen über eine öffentliche REST-API, ein offizielles TypeScript-SDK und eine Next.js-Vorlage mit einem Klick.

Warum das zählt

Das gehostete Karriereportal und das einbettbare Widget von Kit decken die meisten Anforderungen ab. Wenn Sie aber die volle Kontrolle über das Design möchten — eine maßgeschneiderte Karriereseite, eine eigene Landingpage pro Stelle oder eine Jobbörse, die zu Ihrem Produkt passt —, können Sie mit der Public Jobs API Ihre veröffentlichten Stellen auslesen und Bewerbungen direkt in Ihre Kit-Pipeline einreichen, während Kit weiterhin Screening, Phasen, Interviews und die Kommunikation mit Kandidaten übernimmt.

Es gibt außerdem ein offizielles TypeScript-SDK und eine Next.js-Vorlage mit Ein-Klick-Deploy, mit denen Sie in wenigen Minuten eine eigene Jobseite ausliefern — oder Sie überspringen beides und rufen die untenstehenden REST-Endpunkte direkt mit einem beliebigen HTTP-Client auf.

API-Schlüssel

Erstellen Sie ein Schlüsselpaar unter Hiring → Career Portal → Public API Keys. Jedes Paar besteht aus:

  • Publishable Key (pk_…) — kann bedenkenlos im Browser ausgeliefert werden. Er kann veröffentlichte Stellen lesen und Bewerbungen einreichen, sonst nichts, und gibt niemals Kandidatendaten preis. Bevor er Bewerbungen einreichen kann, müssen Sie mindestens eine Bot-Abwehr einrichten — eine Origin-Allowlist oder Ihr eigenes Cloudflare-Turnstile-Widget —, andernfalls werden Bewerbungsanfragen mit 403 bot_protection_required abgelehnt. Das Lesen von Stellen funktioniert auch ohne diese Konfiguration.
  • Secret Key (sk_…) — ausschließlich für die serverseitige Nutzung (z. B. eine Next.js Server Action). Er überspringt die browserseitigen Origin-/Turnstile-Prüfungen. Geben Sie ihn niemals in clientseitigem Code preis. Keiner der beiden Schlüssel kann personenbezogene Kandidatendaten lesen.

Der Secret Key wird nur ein einziges Mal angezeigt — bei der Erstellung oder Rotation. Sie können ihn jederzeit über die Einstellungsseite des Schlüssels rotieren; der vorherige Secret Key verliert sofort seine Gültigkeit.

Authentifizieren Sie jede Anfrage mit einem Bearer-Header:

Authorization: Bearer sk_your_secret_key

Endpunkte

Basis-URL: https://startupkit.app (oder Ihre benutzerdefinierte Karriere-Domain).

Veröffentlichte Stellen auflisten

GET /api/public/v1/jobs?department=&location=&employment_type=&remote=&page=&per_page=

Gibt ausschließlich veröffentlichte Stellen Ihres Kontos zurück.

{
  "data": [
    {
      "id": "JdK2hQ8…",
      "title": "Senior Rails Developer",
      "department": "Engineering",
      "location": "Remote",
      "employment_type": "full_time",
      "remote": true,
      "published_at": "2026-06-01T12:00:00Z",
      "url": "https://careers.yourco.com/JdK2hQ8…",
      "salary": { "min": 120000, "max": 160000, "currency": "USD", "period": "YEAR" }
    }
  ],
  "pagination": { "current_page": 1, "total_pages": 3, "total_count": 42, "per_page": 20 }
}

Die id ist das öffentliche Token der Stelle — verwenden Sie es für die Detail- und Bewerbungs-Endpunkte.

Eine Stelle samt Bewerbungsformular abrufen

GET /api/public/v1/jobs/:public_token

Gibt die Stelle zurück, ergänzt um ein application_form, das genau beschreibt, welche Felder und Fragen zu rendern sind, welcher Einwilligungshinweis anzuzeigen ist, welche Dateitypen und -größen für Lebensläufe akzeptiert werden und ob Turnstile erforderlich ist.

{
  "id": "JdK2hQ8…",
  "title": "Senior Rails Developer",
  "description_html": "<p>We're hiring…</p>",
  "accepting_applications": true,
  "stages": [{ "name": "Application Review", "type": "application_form" }],
  "application_form": {
    "fields": [
      { "name": "cover_letter", "type": "textarea", "label": "Cover letter", "required": false }
    ],
    "questions": [
      { "key": "why_us", "type": "text", "prompt": "Why do you want to join?", "required": true, "max_length": 2000 }
    ],
    "consent_disclosure_html": "<p>By applying you agree…</p>",
    "resume": {
      "content_types": ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
      "max_byte_size": 10485760
    },
    "turnstile": { "required": false, "sitekey": null }
  }
}

Lebenslauf hochladen (presigned)

Lebensläufe werden direkt in den Speicher hochgeladen und passieren daher niemals Ihren Server (das vermeidet Body-Größenlimits in Serverless-Umgebungen).

POST /api/public/v1/direct_uploads
{ "blob": { "filename": "cv.pdf", "byte_size": 102400, "checksum": "<base64 MD5>", "content_type": "application/pdf" } }
{
  "signed_id": "eyJf…",
  "direct_upload": { "url": "https://…s3…", "headers": { "Content-Type": "application/pdf", "Content-MD5": "" } }
}

Senden Sie die Dateibytes per PUT an direct_upload.url mit den zurückgegebenen headers, und übergeben Sie anschließend die signed_id als resume_signed_id, wenn Sie die Bewerbung einreichen.

Bewerbung einreichen

POST /api/public/v1/jobs/:public_token/applications
{
  "application": {
    "email": "[email protected]",
    "first_name": "Ada",
    "last_name": "Lovelace",
    "phone": "+1 555 0100",
    "responses": { "cover_letter": "…", "why_us": "…" },
    "resume_signed_id": "eyJf…"
  },
  "turnstile_token": "<token>"
}

Gibt 201 mit einer minimalen Bestätigung ohne personenbezogene Daten zurück:

{ "id": "app_9fQ…", "status": "submitted", "job": "JdK2hQ8…", "submitted_at": "2026-06-11T09:30:00Z" }

Das turnstile_token wird nur bei Browser-Einreichungen (pk_) benötigt, wenn für den Schlüssel Turnstile konfiguriert ist; serverseitige Aufrufe (sk_) überspringen es.

Fehler

Fehler werden in einem einheitlichen Format zurückgegeben:

{ "error": { "code": "validation_failed", "message": "Email can't be blank", "fields": { "email": ["can't be blank"] } } }
Status Code Bedeutung
401 invalid_key Fehlender oder ungültiger API-Schlüssel
403 bot_protection_required Publishable Key (pk_) hat weder eine Origin-Allowlist noch Turnstile konfiguriert
403 origin_not_allowed Browser-Origin steht nicht auf der Allowlist des Schlüssels
404 not_found Stelle nicht gefunden oder nicht veröffentlicht
409 already_applied Diese E-Mail-Adresse hat sich bereits auf diese Stelle beworben
422 validation_failed Ungültige Bewerbungsfelder (siehe fields)
422 turnstile_failed Turnstile-Verifizierung fehlgeschlagen
422 invalid_content_type / file_too_large Abgelehnter Lebenslauf-Upload

Status-Updates per Webhooks

Um Bewerbungen nach der Einreichung weiterzuverfolgen, konfigurieren Sie ausgehende Webhooks. Relevante Ereignisse sind unter anderem application.submitted, application.advanced und application.rejected sowie job_posting.published/paused/closed. Bewerbungs-Payloads enthalten sowohl die numerische id als auch die API-prefix_id (app_…) sowie das public_token der Stelle, sodass Sie Webhook-Ereignisse mit API-Datensätzen verknüpfen können.

SDK & Next.js-Vorlage

Zwei offizielle, quelloffene Ausgangspunkte setzen auf dem obigen REST-Vertrag auf — nutzen Sie einen davon oder überspringen Sie beide und rufen die Endpunkte direkt mit einem beliebigen HTTP-Client auf.

  • TypeScript-SDK — @startupkit-app/jobs. Ein typisierter, abhängigkeitsfreier Client (natives fetch, ESM + CJS, Node ≥ 18.17), der in Node, Browsern und Edge-Runtimes läuft. Installieren Sie ihn mit npm install @startupkit-app/jobs und dann:

    import { createClient } from "@startupkit-app/jobs";
    
    const kit = createClient({ secretKey: process.env.KIT_SECRET_KEY });
    
    const page = await kit.listJobs({ department: "Engineering", remote: true });
    const job = await kit.getJob(page.data[0].id);
    const { signed_id } = await kit.uploadFile(resumeFile);
    await kit.apply(job.id, { email: "[email protected]", resume_signed_id: signed_id });
    

    Übergeben Sie in Browser-Code publishableKey (pk_…) statt secretKey. Weitere Methoden: allJobs() iteriert asynchron über alle Seiten, und createUpload() bietet feinere Kontrolle über den presigned Upload. Nicht-2xx-Antworten werfen KitApiError (mit .code und .fields); Fehler, die die API nie erreichen, werfen KitNetworkError. Der Client verwendet standardmäßig die Basis-URL https://app.startupkit.app; übergeben Sie baseUrl, um sie für eine benutzerdefinierte Karriere-Domain zu überschreiben.

  • Next.js-Vorlage — nextjs-job-board. Eine produktionsreife Karriereseite (Next.js App Router, Server Components + Server Actions, ISR mit tag-basierter Revalidierung), die Sie forken oder mit einem Klick deployen können. Sie rendert das Bewerbungsformular dynamisch aus dem API-Schema, führt presigned Resume-Uploads direkt in den Speicher durch, gibt schema.org-JobPosting-JSON-LD aus (bereit für Google for Jobs) und revalidiert optional sofort per Webhook. Setzen Sie eine einzige Umgebungsvariable — STARTUPKIT_SECRET_KEY (Ihr sk_…-Schlüssel) — und deployen Sie:

    Deploy with Vercel

    Live-Demo: nextjs-job-board-orcin.vercel.app. Optionale Umgebungsvariablen: STARTUPKIT_BASE_URL (Standard: https://app.startupkit.app), NEXT_PUBLIC_TURNSTILE_SITE_KEY, REVALIDATE_SECRET und NEXT_PUBLIC_COMPANY_NAME.

Beide nutzen den obigen Vertrag, sodass Sie auch mit jedem beliebigen Framework über einfaches HTTP entwickeln können. Eine typische eigene Jobseite verbindet vier Aufrufe: Stellen auflisten, eine Stelle samt Formular abrufen, einen presigned Upload für den Lebenslauf anfordern und die Bewerbung einreichen. Da alles reines JSON über HTTPS ist, funktioniert dieselbe Integration serverseitig (sk_-Schlüssel) wie im Browser (pk_-Schlüssel mit konfigurierter Bot-Abwehr).

Rate Limits

Bewerbungs-Einreichungen sind auf 10/Stunde pro IP begrenzt, Upload-Anfragen auf 30/Stunde pro IP — zusätzlich zu den globalen API-Rate-Limits. Browser-Schlüssel sind außerdem durch ihre Origin-Allowlist und optional durch Turnstile geschützt.

Suchbegriff eingeben...