← API Key JS Staff

Документация API

Отправляйте уведомления сотрудникам из других систем — скрипты, cron на других серверах, n8n, вебхуки, WhatsApp-боты.

Получить API-ключ

Владелец: перейдите в Управление → 🔑 API-ключ, дайте имя, нажмите Создать ключ.

Ключ выглядит как jss_ + 64 символа и показывается только один раз. Сервер хранит только его отпечаток, так что если вы его потеряете, никто не сможет показать его снова — включая нас. Отзовите старый, создайте новый.

Храните его в переменной окружения или в конфигурационном файле вне docroot. Никогда в коде, который попадает в git.

2 · Отправить ключ

Один из этих двух заголовков — выберите тот, что удобнее для вашего инструмента:

Authorization: Bearer jss_xxxxxxxx...
X-API-Key: jss_xxxxxxxx...

Ключ определяет компанию. Ни в одном эндпоинте нет параметра tenant — если бы был, одного утёкшего ключа хватило бы для отправки во все компании платформы.

Здесь нет защиты от CSRF, и это правильно. CSRF защищает от запросов, инициированных чужим браузером с использованием его куки. Запросы по ключу не несут ничьих куки — использовать нечего.

Что может этот ключ

Только отправляет уведомления сотрудникам компании-владельца, а также читает список имён и id сотрудников (чтобы у вас был способ получить user_id без угадывания).

Он не может читать чью-либо зарплату, посещаемость, почту, банковский счёт или уведомления; не может ничего изменить; не может затронуть другие компании. Намеренно настолько ограничен — учётные данные, живущие на чужом сервере, рано или поздно утекут, и степень ущерба зависит от того, как мало они могут сделать.

3 · Проверить, что ключ работает

GET/api/v1/notif.php?aksi=ping

curl "https://staff.jidanshoppu.com/api/v1/notif.php?aksi=ping" \
  -H "Authorization: Bearer jss_xxx"
{ "ok": true, "key": "n8n produksi", "perusahaan": "Perusahaan Kamu" }

4 · Получить список сотрудников

GET/api/v1/notif.php?aksi=karyawan — чтобы получить user_id.

curl "https://staff.jidanshoppu.com/api/v1/notif.php?aksi=karyawan" \
  -H "Authorization: Bearer jss_xxx"
{
  "ok": true,
  "karyawan": [
    { "user_id": 3, "nama": "Sela",   "peran": "staff" },
    { "user_id": 5, "nama": "Syauqi", "peran": "staff" }
  ]
}

Только id, имя и роль. Нет email/ставки/счёта — этот ключ для отправки уведомлений, а не для чтения данных людей.

5 · Отправить уведомление

POST/api/v1/notif.php — принимает JSON или данные формы.

ПолеОбязательноОписание
judulдамакс. 120 символов
isiдамакс. 255 символов
user_idнет id сотрудника. 0 или отсутствует = все активные сотрудники
jenisнет info (по умолчанию), kasbon (аванс), gaji (зарплата), bonus, timer, absen (отметка). Влияет только на значок; неизвестные значения переходят в info
urlнет должен быть внутренним путём, начинающимся с /

Всем сотрудникам

curl -X POST https://staff.jidanshoppu.com/api/v1/notif.php \
  -H "Authorization: Bearer jss_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "judul": "Besok libur",
    "isi": "Tanggal 17 libur, timer tidak perlu dinyalakan."
  }'
{ "ok": true, "terkirim": 5 }

Одному человеку, со ссылкой

curl -X POST https://staff.jidanshoppu.com/api/v1/notif.php \
  -H "X-API-Key: jss_xxx" \
  -d "user_id=3" \
  -d "judul=Cek transaksi kamu" \
  -d "isi=Ada penyesuaian baru bulan ini." \
  -d "jenis=gaji" \
  -d "url=/staff/transaksi.php"
url обязан быть внутренним путём. https://… и //evil.com отклоняются с 400.

Причина: официально выглядящее уведомление, ведущее куда угодно, — идеальный инструмент фишинга: сотрудники кликают без подозрений именно потому, что это доставил портал. Одного утёкшего ключа достаточно, чтобы разослать «Нажмите, чтобы проверить зарплату» на поддельную страницу входа.

//evil.com тоже отклоняется, хотя и начинается с косой черты: браузеры читают это как адрес на другой хост.

Что происходит после отправки

Сотрудники с открытым порталом слышат звук и видят всплывающее окно в течение ≤20 секунд. Те, у кого портал не открыт, увидят уведомление при следующем входе. Всё попадает на их страницу «Уведомления», а каждая отправка через API фиксируется в журнале аудита с именем ключа.

Лимит запросов

60 запросов в минуту на ключ. Каждый ответ содержит:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57

При превышении лимита → 429 + Retry-After: 60.

Коды статуса

КодЗначение
200Успешно
400Неверный параметр, повреждённое тело JSON, или url — не внутренний путь
401Ключ не передан, неверен или уже отозван
404user_id не является сотрудником этой компании
405Неверный метод
429Превышен лимит запросов

Если не работает

СимптомОбычно причина
401, хотя ключ верный Некоторые серверы удаляют заголовок Authorization до того, как он дойдёт до PHP. Попробуйте X-API-Key — обычный заголовок, который сервер никогда не трогает. Если это сработает, а Bearer нет, сообщите нам.
401 внезапно, хотя раньше работало Владелец отозвал ключ. Проверьте страницу API-ключа.
400 «url должен быть внутренним путём» Вы отправили https://…. Используйте /staff/transaksi.php.
200, но "terkirim": 0 Сотрудник неактивен, или у компании ещё нет активных сотрудников.

Честные ограничения

Нужно, чтобы сотрудники входили в ваше приложение с аккаунтом JS Staff (а не только получали уведомления)? Это SSO — руководство по настройке здесь.