Dokumentacja API
Uwierzytelnianie i odpytywanie API rekrutacyjnego w celu uzyskania danych o ofertach pracy, 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
Należy zastąpić startupkit.app rzeczywistą domeną Kit.
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 |
Oferty pracy i etapy rekrutacji |
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_atmoż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: należy tworzyć 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 posiada 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
}
}
Należy użyć parametru ?page=2, aby pobrać kolejne strony.
Oferty pracy
Wymagany zakres: job_postings:read
Lista ofert pracy
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 oferty pracy
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 oferty pracy |
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 posiada 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ążaj za przekierowaniami) w curl.403 Forbidden– Token nie posiada zakresuapplications:readlubcandidates:read.404 Not Found– Aplikacja nie znaleziona lub brak dołączonego CV.
Uwagi:
- Podpisane URL wygasają po 30 minutach. Po wygaśnięciu należy pobrać nowy.
- Nagłówek
Content-Dispositionjest ustawiony naattachment(wymusza pobranie pliku przez przeglądarkę). - Obsługiwane formaty CV: PDF, DOC, DOCX (zgodnie z tym, co przesłał kandydat).
Redakcja danych osobowych kandydata
Gdy token posiada zakres applications:read, ale nie posiada 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
W przypadku odpowiedzi 401 należy sprawdzić:
- Format tokenu: Token powinien być dokładnie taki, jak wyświetlany w Settings > API (32-znakowy ciąg szesnastkowy)
- Nagłówek Authorization: Musi mieć format
Authorization: Bearer TOKENlubAuthorization: token TOKEN - Wygasanie tokenu: Sprawdzić, czy wartość
expires_atnie została przekroczona w Settings > API - Członkostwo w koncie: Upewnić się, że właściciel tokenu nadal jest członkiem konta
403 Forbidden
W przypadku odpowiedzi 403 token jest prawidłowy, ale nie posiada wymaganego zakresu uprawnień:
- Sprawdzenie wymaganych zakresów: Każdy endpoint dokumentuje wymagany zakres (np.
job_postings:read) - Dodanie brakujących zakresów: Edytować token w Settings > API i dodać potrzebny zakres
- Format zakresu: Musi dokładnie odpowiadać wzorcowi —
job_postings:read, a niejob_postingslubread
Problemy z dostępem do danych
Pusta tablica data w odpowiedziach
Jeżeli API zwraca {"data": [], "pagination": {...}}, a spodziewane są wyniki:
- Izolacja kont: Tokeny API widzą tylko dane z konta, do którego są przypisane
- Weryfikacja konta: Sprawdzić, do którego konta należy token w Settings > API
- 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ą ukryte
Jeżeli widoczne jest jedynie {"candidate": {"id": "cand_..."}} bez imienia i adresu e-mail:
- Oczekiwane zachowanie: Dzieje się tak, gdy token posiada zakres
applications:read, ale nie posiada zakresucandidates:read - Dodanie zakresu: Aby zobaczyć pełne dane kandydata, należy dodać zakres
candidates:readdo tokenu - 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
- Prefiksowe ID: Oferty pracy używają formatu
job_abc123, a nie identyfikatorów bazodanowych takich jak42 - Wielkość liter: Prefiksowe ID rozróżniają wielkość liter
- Zakres konta: Zasób musi należeć do konta powiązanego z tokenem
Parametry filtrowania nie działają
- Dopuszczalne wartości statusów:
- Oferty pracy:
draft,published,closed(z uwzględnieniem wielkości liter) - Aplikacje:
active,rejected(z uwzględnieniem wielkości liter)
- Oferty pracy:
- Format parametrów: Należy używać
?status=published, a nie?status=Publishedlub?filter[status]=published
Często zadawane pytania
Jak działa paginacja?
Wszystkie endpointy listowe zwracają 20 elementów na stronę (wartość stała). Aby przejść do następnej strony, należy użyć 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. Należy używać 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 w celu zapewnienia stałej wydajności. Należy używać parametru page do iterowania po wszystkich wynikach.
Szybka lista kontrolna
- Utworzyć token API w sekcji Settings > API — każdy token jest powiązany z danym kontem
- Przypisać tylko te zakresy, których wymaga integracja (zalecana praktyka: jeden token na integrację z minimalnymi zakresami)
- Sprawdzić wartość
expires_atw Settings > API, aby poznać datę wygaśnięcia tokenu (jeśli ustawiona) - Dołączać nagłówek
Authorization: Bearer TOKENdo każdego żądania - Używać prefiksowych ID (np.
job_abc123) w adresach URL zamiast identyfikatorów bazodanowych - Obsługiwać odpowiedzi
400i422w przypadku błędów walidacji - Obsługiwać odpowiedzi
401— token mógł wygasnąć lub zostać unieważniony - Obsługiwać odpowiedzi
403— token może nie posiadać wymaganego zakresu uprawnień - Używać parametru
pagedo paginacji dużych zbiorów wyników (20 elementów na stronę)