Dokumentacja API
Cztery endpointy, jeden nagłówek uwierzytelniający, rozliczenie za rozstrzygnięte cytowanie. Poniżej wszystko, czego potrzeba do integracji — każdy przykład został uruchomiony na produkcji.
Uwierzytelnianie
Klucz w nagłówku Bearer. Nieznany, nieaktywny i brakujący klucz dają ten sam wynik 401 — nie podpowiadamy, która z tych rzeczy zawiodła.
Authorization: Bearer cyt_live_…Dwa rodzaje kluczy
Klucz z prefiksem cyt_test_ korzysta z tego samego korpusu i zwraca te same odpowiedzi, ale nie jest rozliczany — 300 cytowań miesięcznie na integrację i sprawdzenie obsługi błędów. Klucz cyt_live_ obsługuje ruch produkcyjny i liczy się do pakietu. Klucz widzisz jeden jedyny raz przy wydaniu; w bazie trzymamy wyłącznie jego skrót.
Za co płacisz
Jednostką rozliczeniową jest ROZSTRZYGNIĘTE CYTOWANIE — jedno zdanie, do którego znaleźliśmy źródło z numerem strony. Odmowa (found: false) jest bezpłatna. Formatowanie przypisów nie dotyka korpusu i jest bezpłatne w każdym pakiecie. Osobno liczy się NOWY TEMAT: zbudowanie korpusu dla zagadnienia, którego jeszcze nie mamy — trwa minuty i kosztuje dwa rzędy wielkości więcej, dlatego uruchamiasz je świadomie przez harvestOnMiss.
| Pakiet | Cena / mies. | Cytowania | Nowe tematy | Ponad pakiet |
|---|---|---|---|---|
| Test | za darmo | 100 | 3 | — |
| Start | $49 | 1500 | 20 | $0.04 / $1.00 |
| Pro | $199 | 7000 | 100 | $0.04 / $1.00 |
| Scale | $799 | 30 000 | 500 | $0.04 / $1.00 |
Endpointy
GET /usage
Stan pakietu i zużycie w bieżącym miesiącu. Nic nie kosztuje i niczego nie zużywa — najtańszy sposób sprawdzenia, czy klucz działa.
curl -s -H "Authorization: Bearer $CYTADO_KEY" \
https://cytado.com/api/ext/usageimport os, requests
r = requests.get(
"https://cytado.com/api/ext/usage",
headers={"Authorization": f"Bearer {os.environ['CYTADO_KEY']}"},
timeout=60,
)
print(r.json())const r = await fetch("https://cytado.com/api/ext/usage", {
headers: { Authorization: `Bearer ${process.env.CYTADO_KEY}` },
});
console.log(await r.json());POST /find-source
Zdanie na wejściu, źródło z numerem strony na wyjściu. To jedyne wywołanie, za które płacisz — i tylko wtedy, gdy coś znajdzie. Do 60 pozycji w żądaniu; nadmiar odrzucamy JAWNIE. Pole hint to temat pracy: bez niego pytamy „czy to źródło potwierdza to zdanie”, a z nim „czy ktoś piszący TĘ pracę mógłby je zacytować”.
curl -s -X POST https://cytado.com/api/ext/find-source \
-H "Authorization: Bearer $CYTADO_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"id": "a1",
"claim": "Prokrastynacji towarzyszy poczucie winy i dyskomfort psychiczny.",
"hint": "prokrastynacja u studentow"
}
],
"langs": [
"pl"
],
"harvestOnMiss": false
}'import os, requests
r = requests.post(
"https://cytado.com/api/ext/find-source",
headers={"Authorization": f"Bearer {os.environ['CYTADO_KEY']}"},
json={
"items": [
{
"id": "a1",
"claim": "Prokrastynacji towarzyszy poczucie winy i dyskomfort psychiczny.",
"hint": "prokrastynacja u studentow"
}
],
"langs": [
"pl"
],
"harvestOnMiss": False
},
timeout=600,
)
r.raise_for_status()
print(r.json())const r = await fetch("https://cytado.com/api/ext/find-source", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CYTADO_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"items": [
{
"id": "a1",
"claim": "Prokrastynacji towarzyszy poczucie winy i dyskomfort psychiczny.",
"hint": "prokrastynacja u studentow"
}
],
"langs": [
"pl"
],
"harvestOnMiss": false
}),
});
if (!r.ok) throw new Error(`cytado ${r.status}: ${await r.text()}`);
console.log(await r.json());POST /format
Metadane na wejściu, gotowy przypis i pozycja bibliograficzna na wyjściu. Style: apa7 (alias apa), mla, chicago, pl-footnote. Przez include dobierasz postacie: footnote, entry, bibtex, ris. Nie dotyka korpusu, więc jest bezpłatne w każdym pakiecie.
curl -s -X POST https://cytado.com/api/ext/format \
-H "Authorization: Bearer $CYTADO_KEY" \
-H "Content-Type: application/json" \
-d '{
"style": "apa",
"include": [
"footnote",
"entry",
"bibtex",
"ris"
],
"sources": [
{
"title": "Regulacja nastroju a prokrastynacja",
"authors": "Pisarska, A.",
"year": 2020,
"page": 208
}
]
}'import os, requests
r = requests.post(
"https://cytado.com/api/ext/format",
headers={"Authorization": f"Bearer {os.environ['CYTADO_KEY']}"},
json={
"style": "apa",
"include": [
"footnote",
"entry",
"bibtex",
"ris"
],
"sources": [
{
"title": "Regulacja nastroju a prokrastynacja",
"authors": "Pisarska, A.",
"year": 2020,
"page": 208
}
]
},
timeout=600,
)
r.raise_for_status()
print(r.json())const r = await fetch("https://cytado.com/api/ext/format", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CYTADO_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"style": "apa",
"include": [
"footnote",
"entry",
"bibtex",
"ris"
],
"sources": [
{
"title": "Regulacja nastroju a prokrastynacja",
"authors": "Pisarska, A.",
"year": 2020,
"page": 208
}
]
}),
});
if (!r.ok) throw new Error(`cytado ${r.status}: ${await r.text()}`);
console.log(await r.json());POST /chapter-sources
Temat rozdziału na wejściu, zestaw cytowalnych źródeł na wyjściu, uszeregowany pokryciem tematu. Pole exclude pozwala podać źródła już wykorzystane — pokrycie liczymy wtedy po tych, które zostały, więc kolejne rozdziały nie dostają w kółko tego samego.
curl -s -X POST https://cytado.com/api/ext/chapter-sources \
-H "Authorization: Bearer $CYTADO_KEY" \
-H "Content-Type: application/json" \
-d '{
"topic": "czas ekranowy dzieci w wieku przedszkolnym",
"chapter": "Wprowadzenie",
"exclude": []
}'import os, requests
r = requests.post(
"https://cytado.com/api/ext/chapter-sources",
headers={"Authorization": f"Bearer {os.environ['CYTADO_KEY']}"},
json={
"topic": "czas ekranowy dzieci w wieku przedszkolnym",
"chapter": "Wprowadzenie",
"exclude": []
},
timeout=600,
)
r.raise_for_status()
print(r.json())const r = await fetch("https://cytado.com/api/ext/chapter-sources", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CYTADO_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"topic": "czas ekranowy dzieci w wieku przedszkolnym",
"chapter": "Wprowadzenie",
"exclude": []
}),
});
if (!r.ok) throw new Error(`cytado ${r.status}: ${await r.text()}`);
console.log(await r.json());Pola odpowiedzi, które warto rozumieć
- found
- false znaczy, że korpus nie ma czym poprzeć tej tezy. Nie zwracamy wtedy najbliższego dopasowania i nie pobieramy opłaty.
- page_from / page_to
- Numer strony DRUKOWANEJ — ten sam, na który trafi promotor sprawdzający przypis, a nie numer kartki w pliku PDF.
- page_from_label
- Wypełnione tylko przy numeracji nietypowej (np. „E136”). Puste pole przy wypełnionym page_from znaczy „numer drukowany to po prostu 152”, a nie „brak paginacji”.
- relevance
- 9–10: wprost o tej tezie i tej grupie. 7–8: to samo zjawisko w pokrewnym ujęciu — inna grupa zawodowa, inny wiek, inny kraj; cytowalne, ale zaznacz kontekst.
- url
- Odnośnik do oryginału — DOI albo bezpośredni adres. Ma go KAŻDE zwrócone źródło; przy ponad połowie korpusu prowadzi do pełnego tekstu, bo są to publikacje otwarte.
- snippet
- Krótki fragment w ramach dozwolonego użytku. Pełnych tekstów źródeł, których nie wolno nam republikować, nie zwracamy nigdy — zwracamy odnośnik, pod którym czytelnik przeczyta je u wydawcy.
- rozliczenie
- Co dokładnie policzyliśmy w tym żądaniu: liczba cytowań i liczba nowych tematów.
Limity i błędy
- 401 unauthorized
- Nieznany, nieaktywny albo brakujący klucz.
- 400 invalid-json
- Ciało żądania nie jest poprawnym JSON-em.
- 400 missing-items
- Brakuje wymaganego pola `items` (tablica).
- 422 invalid_request
- Żądanie poprawne składniowo, ale niedopuszczalne — np. nieznany styl cytowania.
- 429 rate_limited
- Przekroczony limit. Nagłówek Retry-After mówi, za ile sekund wrócić. Bezpiecznik minutowy mówi „zwolnij”, limit dobowy „na dziś koniec” — komunikat je rozróżnia.
- 402
- Wyczerpany pakiet na operacji, która wymaga opłaconego dostępu.
Zacznij od klucza testowego
300 cytowań miesięcznie, bez rozliczenia i bez karty. Klucz wydasz sobie sam w panelu, zaraz po założeniu konta.
Załóż konto