Logo StartupKit
PL

Dokumentacja API

Uwierzytelnij się i odpytuj API rekrutacyjne, żeby pobrać dane o ogłoszeniach o pracę, kandydatach i aplikacjach.

Dlaczego to ważne

API rekrutacyjne umożliwia systemom zewnętrznym odczyt danych rekrutacyjnych — portale z ofertami pracy pobierają opublikowane ogłoszenia, systemy HRIS synchronizują dane kandydatów, a panele kontrolne śledzą metryki procesu rekrutacji. Zakresy uprawnień tokenu zapewniają, że każda integracja widzi tylko to, czego potrzebuje.

Bazowy URL

Wszystkie endpointy API są dostępne pod adresem:

https://startupkit.app/api/v1

Uwierzytelnianie

Każde żądanie wymaga tokenu API w nagłówku Authorization:

Authorization: Bearer YOUR_TOKEN

Alternatywny format (oba działają):

Authorization: token YOUR_TOKEN

Tokeny można utworzyć w sekcji Settings > API. Każdy token musi mieć jawnie przypisane zakresy uprawnień, aby uzyskać dostęp do endpointów rekrutacyjnych.

Zakres Dostęp
job_postings:read Ogłoszenia o pracę i etapy
candidates:read Dane osobowe kandydatów (imię, e-mail, telefon), pobieranie CV
applications:read Aplikacje, historia etapów, pobieranie CV

Tokeny bez przypisanych zakresów nie mają dostępu do endpointów rekrutacyjnych.

Format i cykl życia tokenu

  • Format: 32-znakowy ciąg szesnastkowy (np. a1b2c3d4e5f6...)
  • Śledzenie ostatniego użycia: Każde udane żądanie aktualizuje pole last_used_at
  • Wygasanie: Opcjonalne pole expires_at można ustawić podczas tworzenia tokenu
  • Alerty o braku aktywności: Tokeny nieużywane przez ponad 30 dni generują powiadomienia dla administratorów
  • Automatyczne unieważnienie: Tokeny są automatycznie unieważniane po usunięciu użytkownika z konta

Zalecana praktyka: twórz osobne tokeny dla każdej integracji z minimalnymi wymaganymi zakresami uprawnień.

Zakres konta

Każdy token API jest powiązany z konkretnym kontem. Konto jest ustalane automatycznie na podstawie tokenu — parametr account_id nie jest wymagany.

Gdy członek zespołu zostanie usunięty z konta, jego tokeny dla tego konta są automatycznie unieważniane.

Odpowiedzi błędów

Status Znaczenie Najczęstsze przyczyny
400 Nieprawidłowe żądanie Brak kontekstu konta (przypadek brzegowy przy uwierzytelnianiu sesyjnym)
401 Brak autoryzacji Brakujący, nieprawidłowy lub wygasły token
403 Brak dostępu Token nie ma wymaganego zakresu uprawnień dla tego endpointu
404 Nie znaleziono Zasób nie istnieje lub nie należy do danego konta
422 Błąd walidacji Błędy walidacji (głównie dla endpointów spoza modułu rekrutacji)

Paginacja

Endpointy listowe zwracają wyniki z paginacją:

{
  "data": [...],
  "pagination": {
    "current_page": 1,
    "total_pages": 3,
    "total_count": 42,
    "per_page": 20
  }
}

Przekaż parametr ?page=2, żeby pobrać kolejne strony.


Ogłoszenia o pracę

Wymagany zakres: job_postings:read

Lista ogłoszeń o pracę

GET /api/v1/job_postings

Przykład:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://startupkit.app/api/v1/job_postings?status=published

Parametry:

Parametr Typ Opis
status string Filtrowanie według statusu: draft, published lub closed
page integer Numer strony

Odpowiedź:

{
  "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": { ... }
}

Pobieranie ogłoszenia o pracę

GET /api/v1/job_postings/:id

Zwraca dane w tym samym formacie co pojedynczy element odpowiedzi listowej.

Lista etapów

GET /api/v1/job_postings/:job_posting_id/stages

Odpowiedź:

{
  "data": [
    {
      "id": "stg_def456",
      "name": "Screening",
      "stage_type": "default",
      "position": 0
    }
  ]
}

Etapy są posortowane według pozycji. Bez paginacji.


Kandydaci

Wymagany zakres: candidates:read

Lista kandydatów

GET /api/v1/candidates

Przykład:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://startupkit.app/api/v1/[email protected]

Parametry:

Parametr Typ Opis
search string Wyszukiwanie według imienia, nazwiska lub adresu e-mail
page integer Numer strony

Odpowiedź:

{
  "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": { ... }
}

Pobieranie kandydata

GET /api/v1/candidates/:id

Zwraca dane w tym samym formacie co pojedynczy element odpowiedzi listowej.


Aplikacje

Wymagany zakres: applications:read

Lista aplikacji

GET /api/v1/applications

Przykład:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://startupkit.app/api/v1/applications?job_posting_id=job_abc123&status=active

Parametry:

Parametr Typ Opis
job_posting_id string Filtrowanie według prefiksowego ID ogłoszenia o pracę
status string Filtrowanie według statusu: active lub rejected
page integer Numer strony

Odpowiedź:

{
  "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": { ... }
}

Pobieranie aplikacji

GET /api/v1/applications/:id

Zwraca dane w tym samym formacie co pojedynczy element odpowiedzi listowej. Gdy token ma zakres candidates:read, a do aplikacji dołączono CV, odpowiedź zawiera metadane CV:

{
  "id": "app_jkl012",
  "resume_filename": "john_doe_resume.pdf",
  "resume_content_type": "application/pdf",
  "resume_byte_size": 245760,
  ...
}

Te pola są pomijane, gdy CV nie jest dołączone lub brakuje zakresu candidates:read.

Pobieranie CV

Wymagane zakresy: applications:read + candidates:read

GET /api/v1/applications/:application_id/resume

Pobiera CV kandydata dla wskazanej aplikacji. Zwraca przekierowanie 302 na podpisany URL z ograniczonym czasem ważności (30 minut).

Przykład:

curl -L -H "Authorization: Bearer YOUR_TOKEN" \
  -o resume.pdf \
  https://startupkit.app/api/v1/applications/app_jkl012/resume

Odpowiedź:

  • 302 Found – Przekierowanie na podpisany URL do pobrania. Użyj -L (podążanie za przekierowaniami) w curl.
  • 403 Forbidden – Token nie ma zakresu applications:read lub candidates:read.
  • 404 Not Found – Nie znaleziono aplikacji lub brak dołączonego CV.

Uwagi:

  • Podpisane URL wygasają po 30 minutach. Po wygaśnięciu pobierz nowy.
  • Nagłówek Content-Disposition jest ustawiony na attachment (wymusza pobranie pliku przez przeglądarkę).
  • Obsługiwane formaty CV: PDF, DOC, DOCX (zgodnie z tym, co przesłał kandydat).

Maskowanie danych osobowych kandydata

Gdy token ma zakres applications:read, ale nie ma zakresu candidates:read, dane kandydata w odpowiedziach dotyczących aplikacji są ograniczone wyłącznie do identyfikatora:

{
  "candidate": {
    "id": "cand_ghi789"
  }
}

Pola first_name, last_name ani email nie są uwzględniane. Dzięki temu integracje z portalami ofert pracy mogą śledzić status aplikacji bez ujawniania danych kontaktowych kandydatów.


Rozwiązywanie problemów

Problemy z uwierzytelnianiem

401 Unauthorized

Jeśli dostajesz odpowiedź 401, sprawdź:

  1. Format tokenu: Token powinien być dokładnie taki, jak wyświetlany w Settings > API (32-znakowy ciąg szesnastkowy)
  2. Nagłówek Authorization: Musi mieć format Authorization: Bearer TOKEN lub Authorization: token TOKEN
  3. Wygasanie tokenu: Sprawdź, czy wartość expires_at nie została przekroczona w Settings > API
  4. Członkostwo w koncie: Upewnij się, że właściciel tokenu nadal jest członkiem konta

403 Forbidden

Gdy dostajesz odpowiedź 403, token jest prawidłowy, ale nie ma wymaganego zakresu uprawnień:

  1. Sprawdź wymagane zakresy: Każdy endpoint dokumentuje wymagany zakres (np. job_postings:read)
  2. Dodaj brakujące zakresy: Edytuj token w Settings > API i dodaj potrzebny zakres
  3. Format zakresu: Musi dokładnie odpowiadać wzorcowi — job_postings:read, a nie job_postings lub read

Problemy z dostępem do danych

Pusta tablica data w odpowiedziach

Jeżeli API zwraca {"data": [], "pagination": {...}}, a spodziewane są wyniki:

  1. Izolacja kont: Tokeny API widzą tylko dane z konta, do którego są przypisane
  2. Weryfikacja konta: Sprawdź, do którego konta należy token w Settings > API
  3. Dostęp między kontami: Tokeny nie mogą uzyskać dostępu do danych z innych kont, nawet jeśli użytkownik jest ich członkiem

Dane osobowe kandydata są zamaskowane

Jeżeli widoczne jest jedynie {"candidate": {"id": "cand_..."}} bez imienia i adresu e-mail:

  1. Oczekiwane zachowanie: Dzieje się tak, gdy token ma zakres applications:read, ale nie ma zakresu candidates:read
  2. Dodaj zakres: Żeby zobaczyć pełne dane kandydata, dodaj zakres candidates:read do tokenu
  3. Ochrona prywatności: Dzięki temu integracje mogą śledzić aplikacje bez ujawniania danych kontaktowych

Problemy z zapytaniami i filtrowaniem

404 przy wyszukiwaniu konkretnych rekordów

  1. Prefiksowe ID: Ogłoszenia o pracę używają formatu job_abc123, a nie identyfikatorów bazodanowych takich jak 42
  2. Wielkość liter: Prefiksowe ID rozróżniają wielkość liter
  3. Zakres konta: Zasób musi należeć do konta powiązanego z tokenem

Parametry filtrowania nie działają

  1. Dopuszczalne wartości statusów:
    • Ogłoszenia o pracę: draft, published, closed (z uwzględnieniem wielkości liter)
    • Aplikacje: active, rejected (z uwzględnieniem wielkości liter)
  2. Format parametrów: Używaj ?status=published, a nie ?status=Published lub ?filter[status]=published

Często zadawane pytania

Jak działa paginacja?

Wszystkie endpointy listowe zwracają 20 elementów na stronę (wartość stała). Żeby przejść do następnej strony, użyj parametru ?page=2. Obiekt pagination zawiera pola total_pages i total_count.

Czy tokeny wygasają automatycznie?

Tylko jeśli podczas tworzenia tokenu ustawiono wartość expires_at. W przeciwnym razie tokeny pozostają ważne do momentu:

  • Ręcznego unieważnienia w Settings > API
  • Usunięcia użytkownika z konta
  • Usunięcia konta

Czy należy używać jednego tokenu dla wielu integracji?

Nie. Zalecana praktyka to jeden token na integrację z minimalnymi zakresami uprawnień. Ułatwia to:

  • Audyt żądań poszczególnych integracji (poprzez pole last_used_at)
  • Unieważnienie dostępu konkretnej integracji bez wpływu na pozostałe
  • Nadawanie różnych uprawnień różnym systemom

Jaki jest związek między webhookami a API?

Webhooki powiadamiają o zdarzeniach (nowa aplikacja, zmiana etapu). API umożliwia odpytywanie bieżącego stanu. Używaj webhooków do wyzwalania działań w systemie, a następnie API do pobierania pełnych danych.

Czy można pobrać więcej niż 20 elementów na stronę?

Nie. Rozmiar strony jest ustalony na 20 elementów, żeby zapewnić stałą wydajność. Używaj parametru page do iterowania po wszystkich wynikach.

W skrócie

  • Utwórz token API w sekcji Settings > API — każdy token jest powiązany z danym kontem
  • Przypisz tylko te zakresy, których wymaga integracja (zalecana praktyka: jeden token na integrację z minimalnymi zakresami)
  • Sprawdź wartość expires_at w Settings > API, żeby poznać datę wygaśnięcia tokenu (jeśli ustawiona)
  • Dołączaj nagłówek Authorization: Bearer TOKEN do każdego żądania
  • Używaj prefiksowych ID (np. job_abc123) w adresach URL zamiast identyfikatorów bazodanowych
  • Obsługuj odpowiedzi 400 i 422 w przypadku błędów walidacji
  • Obsługuj odpowiedzi 401 — token mógł wygasnąć lub zostać unieważniony
  • Obsługuj odpowiedzi 403 — token może nie mieć wymaganego zakresu uprawnień
  • Używaj parametru page do paginacji dużych zbiorów wyników (20 elementów na stronę)

Wpisz, aby wyszukać...