REST API
Przegląd zewnętrznego API Mediflo — adres bazowy, wersjonowanie, koperty odpowiedzi i rodziny endpointów.
Zewnętrzne API Mediflo daje Twojemu systemowi dostęp do tego, co robi Portal: konfiguracji botów głosowych, sesji rozmów, zadań, historii połączeń, próśb o kontakt, webhooków i zgłoszeń do wsparcia. Wszystko przez jeden klucz API z listą zakresów.
Adres bazowy
https://app.mediflo.ai/api/external/v1Kontrakt maszynowy: openapi.json (OpenAPI 3.1, generowany z tych samych schematów Zod, którymi walidują się trasy) oraz llms.txt — zwięzły indeks dla agenta AI konsumującego API.
Wersjonowanie
v1 jest stabilne. Wersja siedzi w ścieżce, więc niekompatybilna zmiana dostanie nową ścieżkę, a nie po cichu zmieni tę. Historia zmian: Changelog.
Pola dodajemy bez zapowiedzi — parsuj odpowiedzi tolerancyjnie i ignoruj nieznane klucze.
Koperty odpowiedzi
| Kształt | Kiedy |
|---|---|
{ "data": { … } } | Pojedynczy obiekt |
{ "data": [ … ], "pagination": { … } } | Lista — patrz Paginacja |
{ "error": { "code", "message", "details?" } } | Każdy błąd — patrz Błędy |
Znaczniki czasu to zawsze łańcuchy ISO 8601 w UTC.
Rozgałęziaj się na `code`, nie na `message`
message jest tłumaczony na język wywołującego i może się zmienić bez zapowiedzi. Stabilny jest wyłącznie code.
Współbieżność
Zapisy, które mogłyby się nadpisać, wymagają wartości, którą przeczytałeś:
- konfiguracja bota —
expectedUpdatedAt, - przepływy rozmowy —
expectedVersion.
Niezgodność to 409 z aktualną wartością w odpowiedzi. Przeczytaj ponownie, scal, ponów.
Rodziny endpointów
Pełna referencja każdej operacji — parametry, schematy, kody odpowiedzi — jest generowana z openapi.json i znajdziesz ją w sekcji Referencja w menu po lewej.
Boty
Tworzenie i konfiguracja botów głosowych, gotowość do rozmów.
Konfiguracja bota
Wersja robocza, publikacja, migawki i wycofanie.
Przepływy rozmowy
Szablony, walidacja bezstanowa, aktywacja.
Procedury
Umiejętności i procedury bota, kolejność wykonania.
Baza wiedzy
Źródła wiedzy, z których bot korzysta w rozmowie.
Sesje botów
Historia rozmów, telemetria per rozmowa, transkrypcje, nagrania i zlecanie połączeń.
Lokalizacje
Placówki, bez których bot nie może istnieć.
Numery telefonów
Numery dostępne do przypisania botom.
Webhooki
Punkty końcowe, dziennik dostarczeń, ponowne wysyłki.
Zgłoszenia
Zgłoś problem do wsparcia Mediflo razem z sesjami, które nie zadziałały.
Słowniki
Rekomendowane ustawienia botów i katalog typów zdarzeń webhook.
Rodziny sprzed OpenAPI
Zadania, użytkownicy, tagi, połączenia i prośby o kontakt są starsze niż generowany kontrakt i nie ma ich w openapi.json. Działają bez zmian; poniżej pełny opis ich powierzchni.
Zadania
| Operacja | Zakres |
|---|---|
GET /tasks | tasks.read |
GET /tasks/{taskId} | tasks.read |
POST /tasks | tasks.write |
PATCH /tasks/{taskId} | tasks.write |
DELETE /tasks/{taskId} | tasks.write |
Parametry GET /tasks: page, limit, status (TODO, IN_PROGRESS, DONE, CANCELLED), priority (LOW, MEDIUM, HIGH, URGENT), assignedToUserId, search, orderBy (createdAt, updatedAt, dueDate, priority, title; domyślnie createdAt), orderDir (asc, desc; domyślnie desc).
Ciało POST /tasks: title (wymagane, do 500 znaków), description, priority (domyślnie MEDIUM), dueDate (ISO 8601), assignedToUserId, tagIds. Odpowiedź 201. PATCH przyjmuje te same pola poza assignedToUserId — przypisania są zarządzane osobno; description i dueDate przyjmują null, żeby wyczyścić wartość, a tagIds zastępuje całą listę tagów.
companyId (UUID firmy z CRM) wiąże zadanie z firmą — tylko w organizacjach z modułem firm (B2B). Pozostałe organizacje dostają 404 TENANT_MODULE_UNAVAILABLE, a nieznana lub usunięta firma daje 422 VALIDATION_ERROR. W PATCH wartość null usuwa powiązanie. Odpowiedzi zawierają pole company ({ id, name } albo null).
curl -s "https://app.mediflo.ai/api/external/v1/tasks?status=TODO&priority=HIGH&limit=20" \
-H "Authorization: Bearer mflo_live_..."{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Oddzwonić w sprawie zgłoszenia",
"status": "TODO",
"priority": "HIGH",
"origin": "SYSTEM",
"dueDate": "2026-09-10T14:00:00.000Z",
"assignedToUser": { "id": "123e4567-e89b-12d3-a456-426614174000", "firstName": "Jan", "lastName": "Kowalski" },
"telephonyCall": { "id": "c9f3a6b8-1234-5678-9abc-def012345678", "fromNumber": "+48123456789", "direction": "inbound" },
"patient": { "id": "a1b2c3d4-5678-90ab-cdef-123456789012", "firstName": "Maria", "lastName": "Nowak" },
"contact": null,
"tags": [{ "id": "tag-uuid-1", "name": "Pilne", "color": "#FF0000" }],
"createdAt": "2026-09-06T10:30:00.000Z",
"updatedAt": "2026-09-06T10:30:00.000Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 234, "totalPages": 12 }
}Dwie rzeczy, które zaskakują:
- Usunięte zadanie zwraca
404 TASK_NOT_FOUND. Usuwanie jest miękkie, ale dla tego API zadanie po prostu znika —GET,PATCHiDELETEodpowiadają tak samo.deletedAtw udanej odpowiedzi jest więc zawszenull. - Uzasadnienie modelu nigdy nie wychodzi na zewnątrz. Dla zadań
origin: "SYSTEM"powstałych z analizy rozmowy rozumowanie modelu opiera się na transkrypcji i zostaje w Mediflo. WidziszsystemSource— zgrubną etykietę producenta — i tyle. Ani tutaj, ani w webhookach, ani w eksportach.
Użytkownicy i tagi
GET /users (zakres users.read) — parametry page, limit, isActive, search; zwraca id, email, firstName, lastName, fullName, imageUrl, isActive, createdAt, lastSeenAt i rolę.
GET /tags (zakres tags.read) — parametry search, includeDeleted; zwraca id, name, color, description, createdAt i twórcę. Zapis użytkowników i tagów nie istnieje w v1 — rób to w Portalu.
Połączenia
GET /calls (zakres calls.read) — historia połączeń telefonicznych, tylko do odczytu. Parametry: page, limit, phoneNumber (E.164, dopasowuje fromNumber albo toNumber), dateFrom, dateTo. Wyniki od najnowszych po startedAt.
curl -s "https://app.mediflo.ai/api/external/v1/calls?phoneNumber=%2B48123456789&limit=20" \
-H "Authorization: Bearer mflo_live_..."{
"data": [
{
"id": "c9f3a6b8-1234-5678-9abc-def012345678",
"direction": "inbound",
"status": "COMPLETED",
"fromNumber": "+48123456789",
"toNumber": "+48221234567",
"startedAt": "2026-09-01T09:15:00.000Z",
"answeredAt": "2026-09-01T09:15:06.000Z",
"endedAt": "2026-09-01T09:18:31.000Z",
"duration": 205,
"totalDuration": 211,
"summary": "Rozmówca przełożył termin.",
"voicemailDetected": false,
"topic": { "id": "topic-uuid", "name": "Zmiana terminu" },
"agentUser": { "id": "user-uuid", "fullName": "Anna Wiśniewska" }
}
],
"pagination": { "page": 1, "limit": 20, "total": 87, "totalPages": 5 }
}duration to czas rozmowy w sekundach liczony od answeredAt (null dla nieodebranych), totalDuration obejmuje dzwonienie, a summary jest generowane przez AI i bywa null, dopóki analiza nie ruszy.
Prośby o kontakt
GET /contact-requests (zakres contact-requests.read) — parametry page, limit, status (PENDING, IN_PROGRESS, HANDLED, EXPIRED, CANCELLED).
POST /contact-requests (zakres contact-requests.write) — phoneNumber albo email jest wymagane, do tego obowiązkowe source (do 100 znaków, np. website, crm) oraz opcjonalnie callerName, sourceIdentifier, reason, priority, expiresAt, metadata, telephonyCallId, dispatcherDispatchId. Zwraca 201 z tym samym kształtem co lista (attempts puste).
Zwracany zestaw pól jest kompletnym kontraktem — pola spoza niego celowo nie wychodzą na zewnątrz.
Dwa własne błędy: CONTACT_REQUEST_INVALID_CALL_REFERENCE i CONTACT_REQUEST_INVALID_DISPATCH_REFERENCE, oba 400, gdy wskazane telephonyCallId / dispatcherDispatchId nie istnieje w Twoim workspace.
Zgodność z Thulium
Zakres thulium.initialize-call obsługuje endpoint inicjujący połączenia wychodzące zgodny z API Thulium — istnieje wyłącznie po to, żeby integracje napisane pod Thulium działały bez przepisywania.
Audyt
Każde uwierzytelnione żądanie do /api/external/v1/* trafia do dziennika audytu Twojego workspace: użyty klucz API, metoda HTTP, endpoint (z identyfikatorami zwiniętymi do :id), wynik oraz identyfikator zasobu, który powstał lub się zmienił. Dotyczy to też żądań, które odrzuciliśmy — brak zakresu, przekroczony limit, operacja, która padła po autoryzacji.
Żądania, które padają zanim klucz rozwiąże się do workspace (klucz błędny, nieznany, wygasły albo unieważniony), nie dają się przypisać do tenanta, więc nie ma ich w Twoim dzienniku — lądują w logach operacyjnych Mediflo.
Ciała żądań i odpowiedzi nigdy nie są przechowywane.