Profil konta — API v1 i MCP | Dokumentacja Nodea
Moduł Profil konta obejmuje odczyt i częściową aktualizację profilu użytkownika tokenu: dane identyfikacyjne, firmę i adres rozliczeniowy, profil VAT (kraj, status firmy, numer VAT z walidacją VIES), numer podatkowy oraz strefę czasową. Dokument opisuje warstwę REST API v1 (/api/v1/profile) oraz narzędzia MCP profile-get i profile-update.
Uwierzytelnianie i zakresy (scopes)
API v1 uwierzytelnia się osobistym tokenem Passport przez nagłówek Authorization: Bearer <token>. Profil operuje wyłącznie na użytkowniku tokenu — nie przyjmuje żadnych identyfikatorów, więc nie istnieje powierzchnia cross-tenant.
account:read— odczyt profilu (GET /profile).account:write— częściowa aktualizacja (PATCH /profile).
Profil jest niebramkowany żadną flagą Pennant — dostęp do konta nigdy nie jest feature-flagowany (tak samo jak w web UI). Limit zapytań: throttle:api-v1 = 240/min na użytkownika tokenu.
Co jest świadomie pominięte (web-only)
Wrażliwe, wymagające potwierdzenia operacje pozostają wyłącznie w web UI i nie są eksponowane przez API v1:
- zmiana adresu e-mail,
- zmiana hasła,
- zarządzanie 2FA (dwuskładnikowe uwierzytelnianie),
- odłączenie dostawcy OAuth,
- upload awatara,
- zmiana waluty rozliczeniowej (w web zablokowana blokadą zerowego salda portfeli).
Pole email jest zwracane w odczycie, ale PATCH /profile nie posiada dla niego reguły — jego przesłanie jest ignorowane (pole nie jest częścią validated()). W odróżnieniu od tego narzędzie MCP profile-update jawnie odrzuca email i password błędem walidacji (patrz sekcja MCP) oraz — inaczej niż API — potrafi zmienić walutę.
API v1 — endpointy
| Metoda | Ścieżka | Scope | Opis |
|---|---|---|---|
| GET | /api/v1/profile | account:read | Profil użytkownika tokenu (dane, firma, adres, VAT, strefa czasowa, waluta). |
| PATCH | /api/v1/profile | account:write | Częściowa aktualizacja dowolnego podzbioru pól ogólnych i VAT. Zwraca zaktualizowany profil. |
GET /profile — odpowiedź
Zwraca ProfileResource — pola: id, name, email, company_name, address, country, is_company (bool), vat_number, vat_validated (bool), vat_validated_at (ISO 8601 lub null), tax_number, timezone, currency (PLN|EUR), created_at. Nigdy nie zwraca sekretów, stanu 2FA, hashy hasła/remember, wierszy dostawców OAuth ani flag administracyjnych.
PATCH /profile — parametry ciała
Każda reguła nosi sometimes — klient może wysłać dowolny podzbiór pól; pominięte pola pozostają nietknięte (partial update).
name(string,sometimes|required, max 255) — przesłana nazwa nie może być pusta.company_name(string|null, max 255).address(string|null, max 1000).tax_number(string|null, max 64).timezone(string|null, regułatimezone— identyfikator IANA).country(string|null,size:2— ISO 3166-1 alpha-2).is_company(boolean).vat_number(string|null, max 32).
Waluta nie jest przyjmowana przez API — zmiana currency jest web-only (i dostępna w MCP). Pola ogólne (name, company_name, address, tax_number, timezone) są zapisywane tylko, gdy obecne w ładunku.
Profil VAT i re-walidacja VIES
Przesłanie któregokolwiek z pól country / is_company / vat_number unieważnia poprzednią walidację VIES: vat_validated jest ustawiane na false, a vat_validated_at na null. Następnie, gdy efektywny profil (przesłane wartości nałożone na zapisane) jest firmą (is_company = true) z jednocześnie ustawionym krajem i numerem VAT, wykonywany jest round-trip do VIES (ViesValidator). Kraj i numer VAT są normalizowane (upper-case, trim). Jak w web: nieudany lookup VIES i tak zapisuje przesłane wartości — pole vat_validated pozostaje po prostu false (brak gałęzi odwrotnego obciążenia). VIES używa SOAP (nie fasady Http) i poza produkcją domyślnie działa w trybie sandbox (billing.vies.sandbox).
Kody błędów
401— brak/niepoprawny token.403— brak wymaganego scope (account:readprzy GET,account:writeprzy PATCH).422— walidacja (np. pustyname,countryspozasize:2, nieprawidłowa strefa czasowa).
Przykłady — API
Odczyt profilu
curl -s https://app.nodea.io/api/v1/profile \
-H "Authorization: Bearer $NODEA_TOKEN" \
-H "Accept: application/json"
Aktualizacja danych ogólnych i strefy czasowej
curl -s -X PATCH https://app.nodea.io/api/v1/profile \
-H "Authorization: Bearer $NODEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Jan Kowalski",
"company_name": "Kowalski sp. z o.o.",
"address": "ul. Przykładowa 1, 00-001 Warszawa",
"timezone": "Europe/Warsaw"
}'
Ustawienie profilu VAT (wyzwala re-walidację VIES)
curl -s -X PATCH https://app.nodea.io/api/v1/profile \
-H "Authorization: Bearer $NODEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"is_company": true,
"country": "PL",
"vat_number": "PL1234567890"
}'
MCP — narzędzia
Narzędzia MCP dzielą model uwierzytelniania i zakresów z API v1 (Bearer + scope sprawdzany w ensureScope). Profil jest niebramkowany flagą, więc oba narzędzia są zawsze widoczne w tools/list. Operują wyłącznie na użytkowniku tokenu.
| Narzędzie | Scope | Tryb | Opis |
|---|---|---|---|
| profile-get | account:read | read-only | Zwraca profil: name, email, company_name, adres, country, status firmy/VAT, tax_number, strefę czasową i walutę. Bez poświadczeń i stanu 2FA. |
| profile-update | account:write | idempotentne | Częściowa aktualizacja; tylko przesłane pola się zmieniają. Dodatkowo obsługuje currency. Odrzuca email/password. |
profile-get
Bez parametrów. Odpowiedź jest nadzbiorem ProfileResource — te same pola plus effective_timezone (rozwiązana strefa czasowa użytkownika, gdy timezone jest null).
profile-update — parametry
Wszystkie opcjonalne; zmieniają się tylko przesłane. Puste stringi / null czyszczą pole (blank → null), kraj i numer VAT są upper-case.
name(string, max 255).company_name(string, max 255; null/pusty czyści).address(string, max 1000; null/pusty czyści).tax_number(string, max 64; null/pusty czyści).timezone(string — identyfikator IANA; null czyści).country(string — ISO 3166-1 alpha-2; null czyści).is_company(boolean).vat_number(string, max 32; null/pusty czyści).currency(enumPLN|EUR) — zablokowana, gdy którykolwiek portfel ma niezerowe saldo (zwraca błąd narzędzia); zmiana jest logowana do dziennika aktywności.
Różnice względem API: zmiana pól VAT (country/is_company/vat_number) na wartość różną od zapisanej resetuje vat_validated (i vat_validated_at), ale to narzędzie nie wykonuje round-tripu do VIES — ponowną walidację przeprowadza web UI. Przesłanie email lub password kończy się błędem walidacji (reguła prohibited: „The email address / password can only be changed in the web UI.”), a nie cichym zignorowaniem jak w API.
Przykład — MCP (JSON-RPC)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "profile-get",
"arguments": {}
}
}
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "profile-update",
"arguments": {
"is_company": true,
"country": "PL",
"vat_number": "PL1234567890",
"timezone": "Europe/Warsaw"
}
}
}