Podlacz konta
Dodaj profile w sekcji Konta i sprawdz, czy synchronizacja pobiera publikacje, komentarze oraz metryki.
Produkt, integracje i technologia
Przewodnik po aplikacji dla uzytkownikow, opis architektury dla deweloperow oraz stabilna referencja publicznego API.
{
"site_id": 12,
"title": "Artykul przez API",
"content_html": "<h2>Wprowadzenie</h2><p>Tresc...</p>",
"metadata_json": {
"source_record_id": "article-123"
}
}
Dla uzytkownika
Mumro laczy konta spolecznosciowe, planowanie publikacji, moderacje komentarzy, analityke oraz narzedzia wspierane przez AI w jednym panelu.
Dodaj profile w sekcji Konta i sprawdz, czy synchronizacja pobiera publikacje, komentarze oraz metryki.
Utworz tresc, wybierz konta, dodaj media i zaplanuj termin albo zapisz material jako szkic.
Kontroluj kolejke, opublikowane tresci, komentarze i analityke. Bledy publikacji wymagaja sprawdzenia przed ponowieniem.
Jedna przestrzen moze miec jedna strone Facebook i jedno profesjonalne konto Instagram. Jezeli jedno konto logowania Meta zarzadza kilkoma markami, wybierz dokladnie jeden profil odpowiadajacy aktywnej przestrzeni. Gdy Meta zwroci kilka profili tego samego typu, Mumro nie doda zadnego z nich i poprosi o ponowienie.
| Obszar | Do czego sluzy | Co warto kontrolowac |
|---|---|---|
| Pulpit | Szybki obraz aktywnosci organizacji. | Alerty, ostatnie publikacje i stan kont. |
| Plan i kolejka | Przygotowanie i harmonogramowanie tresci. | Termin, strefa czasowa, konta oraz media. |
| Opublikowane | Historia wyslanych materialow i ich statusow. | Bledy czesciowe, linki do platform i ponowienia. |
| Komentarze | Moderacja i obsluga reakcji odbiorcow. | Konto, autor, tresc i stan obslugi. |
| Analityka | Porownanie wynikow kont i publikacji. | Zakres dat, wybrane konta i znaczenie metryk. |
| Konta | Polaczenia z obslugiwanymi platformami. | Wygasle uprawnienia i czas ostatniej synchronizacji. |
| Harmonogramy | Powtarzalne zasady publikowania. | Dni, godziny, aktywnosc i docelowe konta. |
| WWW i generatory AI | Tworzenie artykulow, postow i materialow pomocniczych. | Szkic przed publikacja oraz reczna weryfikacja tresci. |
Widoczne funkcje zaleza od roli uzytkownika, konfiguracji organizacji i wlaczonych
modulow. Pelny przewodnik znajduje sie takze w pliku
docs/user-guide.md.
Jedna domena, jedno miejsce konfiguracji
Ekran Strona WWW → Konfiguracja strony laczy stan integracji, wspolny kod instalacyjny oraz polaczenie publikacji artykulow dla wybranej domeny.
Rekord strony jest wspolny dla analityki, chatbota i docelowego CMS.
Wybierz bota i aktywuj go dla domeny. Mumro zachowa jego pozostale dozwolone domeny.
Skonfiguruj WordPress albo wlasny endpoint i sprawdz polaczenie przed publikacja.
<script async src="https://app.mumro.io/api/website-analytics/script.js?p=wa_REPLACE_ME"></script>
<script async src="https://app.mumro.io/api/chatbot/widget.js?b=cb_pub_REPLACE_ME"></script>
Analityka korzysta z website-analytics/script.js?p=wa_..., a chatbot z
chatbot/widget.js?b=cb_pub_.... Dwa identyczne kody widgetu nie wlaczaja
analityki. Zawsze kopiuj aktualny blok z Konfiguracji strony.
Instrukcja dla uzytkownika
Modul Artykuly WWW jest prostym CMS-em. Artykul najpierw powstaje jako lokalny szkic w Mumro, a dopiero wybrana akcja wysyla jego aktualna wersje do WordPressa albo wlasnej integracji strony.
Wybierz domene w Konfiguracji strony. Kazdy artykul jest przypisany do jednej strony.
W Konfiguracji strony ustaw WordPress albo wlasny endpoint i uzyj przycisku Testuj.
Zapisz lokalny szkic, wyslij szkic do CMS, zaplanuj publikacje albo publikuj od razu.
Podaj adres glownej strony, uzytkownika WordPress i jego Application Password.
Nie uzywaj zwyklego hasla logowania. Uzytkownik WordPress musi miec prawo tworzenia i edycji wpisow.
Podaj endpoint HTTPS przygotowany przez dewelopera i wspolny Bearer token.
Na stronie klienta nie jest potrzebne logowanie uzytkownika. Endpoint uwierzytelnia Mumro na podstawie sekretnego tokenu.
Edytor obsluguje akapity, naglowki H2/H3, pogrubienie, kursywe, cytaty, listy, linki, obrazy do 20 MB, tryb HTML oraz osadzenia wideo z YouTube, Vimeo, Facebooka, TikToka i Dailymotion. Ostateczny wyglad i dopuszczalny HTML zaleza od docelowego CMS i stylow strony.
| Akcja | Co sie dzieje |
|---|---|
| Zapisz szkic | Zapisuje artykul tylko lokalnie w Mumro. |
| Wyslij jako szkic | Tworzy albo aktualizuje zdalny szkic w CMS. |
| Zaplanuj w CMS | Wymaga przyszlej daty i wysyla status future. |
| Publikuj teraz | Tworzy albo aktualizuje opublikowany wpis. |
Z jednego miejsca pod edytorem utworzysz rolke tekstowa, karuzele ze szkicowym podgladem albo pojedynczy post promujacy artykul. Tryb Portal moze cyklicznie pobierac kolejne, jeszcze niewykorzystane wpisy z wybranej strony. Promocja social w trybie smart daje Instagramowi i Facebookowi pelna karuzele, X i LinkedIn pojedyncza grafike, a link umieszcza w odpowiednim miejscu.
W Autopilocie artykulow wlacz Pelny autopilot, aby zachowac kolejnosc research → artykul → grafiki → publikacja artykulu → posty social. Kazdy kanal ma osobny job i osobny status, a X przy recznej karuzeli otrzymuje najwyzej cztery slajdy. Lokalny lub zdalny szkic nie uruchamia promocji, dopoki artykul nie stanie sie publiczny.
W sekcji Jezyki publikacji Autopilota artykulow ustaw jezyk
glowny. Steruje on jednoczesnie trescia artykulu, napisami na grafikach,
opisami postow i wezwaniem do przejscia do artykulu. Dodatkowe jezyki
tworza osobne wersje tylko artykulu: nie powielaja grafik ani publikacji
social. Powiazane wersje na mumro.io prowadza do siebie przez
przelacznik jezyka.
Podglad kosztu sumuje article.generate, kazde
article.translate, opis social i opcjonalny obraz AI. Dla
wbudowanych kredytow domyslna cena jednego tlumaczenia wynosi 75 kredytow.
Zadanie asynchroniczne rezerwuje kredyty przed startem, rozlicza je po
sukcesie i zwalnia po bledzie.
Autopilot pozwala wybrac profil RSS i domen albo Tavily, Brave Search czy SerpAPI. Klucz wyszukiwarki dziala niezaleznie od modelu piszacego, a profil z RSS nie wymaga takiego klucza. Nowy formularz domyslnie wybiera pierwszy aktywny profil i limit 10 zrodel. Glowny brief, dodatkowe zapytania, pierwszy priorytet z wytycznych, zrodla oficjalne i niezalezne analizy otrzymuja osobna pule wynikow. W podgladzie widac date publikacji, trafnosc i zapytanie dla kazdego zrodla. Po napisaniu tekstu osobny fact-check usuwa niepotwierdzone premiery, wersje modeli, daty i liczby. Audyt z krytyczna luka albo linkiem spoza researchu zatrzymuje zapis. Oficjalny obraz z RSS moze trafic na okladke, a najwazniejsze punkty do bloku W skrocie na stronie. Brak dzialajacych zrodel lub niespelnienie minimalnej liczby materialow, zrodel oficjalnych i domen przerywa generowanie przed utworzeniem i publikacja artykulu. Tryb bez researchu trzeba wybrac swiadomie i jest przeznaczony do tresci evergreen, nie do biezacych newsow.
Artykul jest tylko archiwizowany lokalnie. Zdalny wpis trzeba usunac bezposrednio w WordPressie albo wlasnym CMS.
Statusy lokalne to draft, scheduled, published,
failed i archived. Przy statusie failed sprawdz komunikat
bledu przy artykule, popraw konfiguracje lub dane i ponow publikacje. Po awarii sieci sprawdz
rowniez strone docelowa, bo CMS mogl zapisac wpis mimo utraty odpowiedzi.
Dla dewelopera
System sklada sie z API, dwoch aplikacji webowych, procesow asynchronicznych i osobnej statycznej dokumentacji.
Python 3.11, Pydantic, Alembic i PostgreSQL.
Vite, TanStack Query, Tailwind, Zod i Recharts.
Publikacje, synchronizacja oraz zadania okresowe.
Pliki trafiaja do magazynu obiektowego, np. S3 lub MinIO.
mumro - API, worker i glowna aplikacja.mumro-admin - panel administracyjny.docs.mumro.io - dokumentacja produktu i API.| Warstwa | Odpowiedzialnosc | Glowna zasada |
|---|---|---|
| API | Autoryzacja, walidacja i operacje domenowe. | Kazde zapytanie musi respektowac organizacje i role. |
| Baza danych | Stan publikacji, kont, komentarzy i analityki. | Migracje Alembic sa jedynym zrodlem zmian schematu. |
| Worker | Operacje zewnetrzne i dlugotrwale. | Zadania powinny byc odporne na ponowienie. |
| Frontend | Obsluga procesu uzytkownika i prezentacja stanu. | Komunikaty musza pokazywac bledy czesciowe i ograniczenia. |
| Integracje | Platformy spolecznosciowe, storage i obserwowalnosc. | Tokeny i sekrety nie moga trafiac do logow ani klienta. |
Rozszerzony opis znajduje sie w docs/technical-overview.md.
Kontrakt integracyjny i przyklady zapytan sa opisane ponizej w sekcjach API.
Callback Meta zapisuje poprawny wynik atomowo, odrzuca wielokrotny wybor profili, a backend i baza wymuszaja jeden Instagram oraz jeden Facebook na przestrzen. Reconnect aktualizuje wylacznie ten sam identyfikator profilu.
Dla wlasciciela i administratora
Mumro powinno przechodzic etapami od lokalnego developmentu, przez prywatny VPS i zamknieta bete, do publicznej uslugi.
Dane testowe, mocki i szybkie testy modulow.
Ograniczone moduly, HTTPS, backup i jedna zaufana osoba.
Zaproszeni uzytkownicy, monitoring i aktywny support.
Billing, retencja, zgodnosc prawna i testy obciazenia.
Rozszerzony opis bramek znajduje sie w
docs/deployment-and-security.md. Sam poprawny start
kontenerow nie oznacza gotowosci do publicznego udostepnienia.
Dla agentow i deweloperow
Klucz smm_... pobierz w aplikacji z Settings -> API keys.
Klucz jest przypisany do organizacji, dlatego nie wymaga X-Organization-Id.
Operacje zapisu i publikacji wymagaja roli member+.
GET /api/website-analytics/sites zawsze zwraca tablice; wybierz poprawna domene.
POST /api/website-articles z unikalnym Idempotency-Key.
POST /api/website-articles/{id}/visuals tworzy okladke lub karuzele 4:5 albo 1:1.
POST /api/website-articles/{id}/publish i sprawdz status w body.
Organizacja jest workspace/tenantem API, a site_id identyfikuje nalezaca
do niej strone WWW. Nie jest to identyfikator workspace.
Zwykle konfiguracje wykonuje uzytkownik w UI. Agent moze jednak dodac strone przez
POST /api/website-analytics/sites, zapisac integracje przez
PUT /api/website-analytics/sites/{site_id}/cms i sprawdzic ja przez
POST /api/website-analytics/sites/{site_id}/cms/test.
{
"cms_type": "wordpress",
"cms_endpoint_url": "https://example.com",
"cms_username": "mumro-publisher",
"cms_secret": "WORDPRESS_APPLICATION_PASSWORD"
}
{
"cms_type": "custom",
"cms_endpoint_url": "https://example.com/api/mumro/articles",
"cms_secret": "LONG_RANDOM_SHARED_BEARER_TOKEN"
}
API nie zwraca zapisanego sekretu; pokazuje tylko cms_has_secret. Pominiecie
cms_secret przy aktualizacji zachowuje obecny sekret, a clear_secret=true
go usuwa.
curl https://app.mumro.io/api/website-analytics/sites \
-H "Authorization: Bearer smm_REPLACE_ME"
curl -X POST https://app.mumro.io/api/website-articles \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"site_id": 12,
"title": "Artykul utworzony przez API",
"slug": "artykul-utworzony-przez-api",
"excerpt": "Krotki opis",
"content_html": "<h2>Wprowadzenie</h2><p>Tresc artykulu.</p>",
"metadata_json": {
"source": "customer-crm",
"source_record_id": "article-123"
}
}'
curl -X POST https://app.mumro.io/api/website-articles/123/visuals \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: article-123-visual-v1" \
-d '{
"visual_style": "editorial",
"cover_mode": "template",
"visual_format": "square",
"content_density": "detailed",
"brand_label": "Mumro",
"carousel_enabled": true,
"slide_count": 6,
"include_sources_slide": true,
"use_as_featured_image": true
}'
Wynik ma format 1080 x 1350 px albo 1080 x 1080 px (zalezne od visual_format) i wraca w polu visual_bundle artykulu.
Uporzadkowane carousel_asset_ids mozna od razu wykorzystac przy publikacji
social media z image_mode="carousel". Tryb template nie zuzywa
kredytow obrazu; cover_mode="ai" wymaga gotowego generatora obrazow i
rozlicza image.generate.
curl -X POST https://app.mumro.io/api/website-articles/123/publish \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{"remote_status":"publish"}'
W module Artykuly WWW sekcja Pakiet wizualny pozwala ustawic styl, tlo szablonowe,
AI albo zrodlo, format 4:5/1:1, ilosc tresci, etykiete marki, liczbe slajdow i slajd zrodel. Podglad pojawia sie
od razu po wygenerowaniu. Te same ustawienia mozna zapisac w harmonogramie
Autopilota artykulow. Przycisk zapisu i lista harmonogramow pokazuja, czy
wybrano szkic, czy publikacje. Aktywny nowy harmonogram zleca pierwszy
przebieg natychmiast; awaryjny sweep podejmuje go w ciagu pieciu minut,
jezeli broker byl chwilowo niedostepny. Mozna tez wybrac date i godzine
pierwszego startu, zobaczyc piec kolejnych terminow oraz uruchomic dodatkowy
przebieg teraz bez przesuwania cyklu. Bledy 401/403/404/422/429 zatrzymuja operacje;
tlo AI moze dodatkowo zwrocic 402 lub 502.
Awaria zewnetrznego CMS moze zostac zapisana jako HTTP 200 z
status="failed" i niepustym last_publish_error. Sukces oznacza
oczekiwany status draft, scheduled albo published
oraz last_publish_error=null.
| Pole | Wymagane | Znaczenie |
|---|---|---|
site_id | Tak | Id polaczonej strony. |
title | Tak | Tytul, 1-180 znakow. |
slug | Nie | Maks. 220 znakow; pusty jest generowany z tytulu. |
excerpt | Nie | Zajawka, maks. 1000 znakow. |
content_html | Nie | HTML artykulu, maks. 200 000 znakow. |
scheduled_at | Nie | Data ISO-8601 uzywana przy statusie future. |
metadata_json | Nie | Metadane integracji; trafiaja do wlasnego CMS. |
| remote_status | Rezultat |
|---|---|
draft | Wysyla lub aktualizuje zdalny szkic. |
publish | Publikuje od razu. |
future | Wymaga przyszlego scheduled_at. |
Dla jednego logicznego utworzenia zawsze ponawiaj ten sam Idempotency-Key. Pierwszy
request zwraca 201, identyczna powtorka 200 i ten sam artykul, a ten sam
klucz z innym payloadem zwraca 422 idempotency_key_conflict. Nowy artykul musi dostac
nowy klucz.
Mumro testuje endpoint przez GET z Bearer tokenem. Przy publikacji wysyla
POST z naglowkami X-Mumro-Article-Id i X-Mumro-Site-Id
oraz obiektem article i site.
{
"article": {
"id": 123,
"external_id": null,
"title": "Tytul",
"slug": "tytul",
"excerpt": "Zajawka",
"content_html": "<p>Tresc</p>",
"status": "publish",
"scheduled_at": null,
"metadata": { "source_record_id": "article-123" }
},
"site": {
"id": 12,
"name": "Strona klienta",
"site_url": "https://example.com",
"domain": "example.com"
}
}
Endpoint powinien dzialac jako upsert: najpierw po article.external_id, a gdy go nie
ma, po stabilnej parze site.id + article.id. To zabezpiecza przed duplikatami po
utracie odpowiedzi sieciowej.
{
"external_id": "post-456",
"external_url": "https://example.com/blog/tytul",
"status": "published"
}
Uzywaj HTTPS, dlugiego losowego Bearer tokenu, porownania constant-time, limitu rozmiaru requestu, walidacji body i sanitizacji HTML. Nigdy nie loguj tokenu.
Pierwszy request
API akceptuje token Bearer. Najprostszy przeplyw to wygenerowanie klucza API w aplikacji, wybranie przykladu pasujacego do procesu i wyslanie requestu z naglowkiem autoryzacji. Artykul zawsze najpierw powstaje jako lokalny szkic, a publikacja jest osobnym requestem.
W aplikacji przejdz do Settings -> API keys i utworz nowy klucz smm_....
Skorzystaj z sekcji Przyklady: artykul WWW, post, reel, story, film albo kolejka.
Dodaj Authorization, a dla tworzenia publikacji takze Idempotency-Key.
Trzymaj klucz w menedzerze sekretow lub zmiennej srodowiskowej. Jesli klucz wycieknie, odwolaj go i wygeneruj nowy. Klucz wklejony do rozmowy, ticketu albo logu traktuj jako ujawniony; nie zapisuj go w raporcie z testu.
Authentication
API przyjmuje token Bearer: klucz API smm_... wygenerowany w UI albo JWT z sesji SPA.
Klucze API sa przypisane do organizacji, dlatego naglowek X-Organization-Id jest dla
nich opcjonalny. Nowy klucz dziedziczy aktualna role organizacyjna osoby, ktora go utworzyla.
Authorization: Bearer smm_REPLACE_ME
Klucz jest widoczny tylko raz przy tworzeniu. Jesli go utracisz, odwolaj stary klucz i wygeneruj nowy.
X-Organization-Id| Principal | Naglowek wymagany? |
|---|---|
API key smm_... |
Nie, klucze sa org-scoped. |
| JWT, uzytkownik jednej organizacji | Nie, organizacja jest wywnioskowana. |
| JWT, uzytkownik z co najmniej 2 aktywnymi czlonkostwami | Tak, ustaw X-Organization-Id. |
Brak naglowka dla multi-org JWT zwraca 401 organization_required.
Odczyt stron i artykulow wymaga roli viewer+. Tworzenie, edycja, archiwizacja
i publikacja artykulow wymaga member+.
Idempotency
Aby bezpiecznie ponawiac requesty po awariach sieci, dolacz naglowek Idempotency-Key.
Wartoscia moze byc UUID v4 albo string o dlugosci 16-128 znakow. Okno idempotencji trwa 24 godziny
od pierwszego sukcesu, a serwer odsyla wartosc w Idempotency-Key-Echo.
Idempotency-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479
| Sytuacja | Odpowiedz |
|---|---|
| Identyczny payload w ciagu 24 godzin | 200 z cache'owanym body pierwszego sukcesu. |
| Inny request z tym samym kluczem jest nadal przetwarzany | 409 z error_code: idempotency_in_progress. |
| Ten sam klucz, inny payload | 422 z error_code: idempotency_key_conflict. |
| Niepoprawny format klucza | 400 z error_code: idempotency_key_invalid. |
POST /api/website-articles przechowuje klucz razem z artykulem. Pierwszy request
zwraca 201, identyczna powtorka 200, a ten sam klucz z innym payloadem
422 idempotency_key_conflict. Klucz pozostaje przypisany do tego artykulu i nie
wygasa po ogolnym 24-godzinnym oknie publikacji social media.
Rate limits
Limity sa naliczane per klucz API albo per JWT subject z uzyciem sliding window. Udane odpowiedzi
zawieraja naglowki X-RateLimit-Limit, X-RateLimit-Remaining i
X-RateLimit-Reset. Po przekroczeniu budzetu API zwraca 429 z
error_code: rate_limited oraz Retry-After.
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1718524800
Retry-After: 17
Errors
Kazda odpowiedz >= 400 zwraca kanoniczna koperte. request_id pochodzi z
naglowka X-Request-Id, a lista error_code jest zamknieta i zdefiniowana
w app.services._errors.ERROR_CODES.
{
"error_code": "validation_error",
"error_message": "Walidacja zadania nie powiodla sie",
"request_id": "1a2b3c...",
"details": null
}
| error_code | HTTP | Opis |
|---|---|---|
missing_bearer_token | 401 | Brak naglowka Authorization albo cookie. |
invalid_api_key | 401 | Klucz API jest odwolany albo nieznany. |
organization_required | 401 | Multi-org JWT musi ustawic X-Organization-Id. |
organization_forbidden | 403 | Principal nie nalezy do wybranej organizacji. |
tenant_forbidden | 403 | Operacja wymaga wyzszej roli OrgRole. |
validation_error | 422 | Walidacja body albo query w Pydantic nie powiodla sie. |
idempotency_in_progress | 409 | Ten sam Idempotency-Key jest nadal przetwarzany. |
idempotency_key_conflict | 422 | Klucz idempotencji zostal uzyty z innym payloadem. |
idempotency_key_invalid | 400 | Niepoprawny format Idempotency-Key. |
target_not_found | 404 | Jeden z targetow nie nalezy do tenanta. |
api_route_not_found | 404 | Nieznana trasa /api/*; odpowiedz jest JSON-em, nigdy HTML-em SPA. |
all_targets_failed | 422 | Wszystkie targety publikacji zakonczyly sie bledem. |
platform_does_not_support_type | 422 | Platforma konta nie obsluguje danego publication_type. |
schedule_required_for_custom | 422 | schedule_mode='custom' wymaga terminu publikacji. |
invalid_schedule_update | 422 | Patch harmonogramu laczy niezgodne pola, np. schedule_source='auto' z scheduled_at. |
invalid_status_transition | 409 | Cancel albo retry zostal wywolany dla niezgodnego statusu joba. |
first_comment_retry_unavailable | 409 | Brak danych posta lub providera potrzebnych do ponowienia pierwszego komentarza. |
scheduled_at_in_past | 400 | PATCH scheduled_at wskazuje przeszlosc. |
media_too_large | 413 | Upload przekracza limit rozmiaru dla typu mediow. |
rate_limited | 429 | Przekroczono limit per klucz. |
account_not_found | 404 | account_id nie nalezy do wybranego tenanta. |
website_analytics_site_not_found | 404 | site_id nie nalezy do wybranego tenanta. |
website_article_not_found | 404 | Artykul nie istnieje, jest zarchiwizowany albo nalezy do innej organizacji. |
website_cms_invalid_config | 422 | Konfiguracja CMS jest niekompletna albo niepoprawna. |
website_cms_not_configured | 422 | Proba publikacji bez skonfigurowanego CMS. |
website_article_invalid_state | 422 | Niepoprawny stan publikacji, np. brak przyszlej daty. |
Dla endpointu publikacji artykulu zawsze sprawdzaj pola status i
last_publish_error. status="failed" oznacza nieudana publikacje.
Przeglad
Jeden klucz smm_... obejmuje caly tenantowy interfejs: publikacje, generatory AI,
analitykę, integracje i narzedzia tekstowe. Ponizej skrocony przeglad obszarow. Pelny katalog
z polami i statusami znajduje sie w docs/api-reference.md, a maszynowy kontrakt
w https://app.mumro.io/openapi.json.
Jedna publikacja rozbijana na wiele kanalow, harmonogram, kolejka i ponawianie.
POST /api/publicationsGET /api/publish-jobsPosty, rolki, shorty i artykuly z researchu. Generacja rozliczana w kredytach.
POST /api/post-generator/generatePOST /api/reels/jobs · /api/shorts/jobsNajlepsze godziny i hashtagi, kandydaci do recyklingu oraz zaangazowanie per kanal — z wlasnych danych.
GET /api/analytics/posting-suggestionsGET /api/analytics/hashtag-suggestionsGET /api/analytics/recycling-candidatesGET /api/analytics/channel-engagementGET /api/analytics/reportPodpisane (HMAC-SHA256) zdarzenia do Twoich systemow: publikacje, leady, artykuly.
GET/POST /api/webhooksPOST /api/webhooks/{id}/testWspolny ton, fakty i slowa kluczowe wstrzykiwane do generatorow postow, artykulow, chatbota i AI komentarzy. Bez kosztu.
GET/PUT /api/brand-voiceSzablony parametrow UTM per przestrzen i tagowanie linkow przed publikacja.
GET/PUT /api/campaigns/settingsPOST /api/campaigns/tag-urlHostowana mini-strona z linkami i CTA pod profil social. Bezpieczne linki (tylko http/https) i gotowy URL.
GET/PUT /api/link-in-bio/pageGET /api/link-in-bio/p/{key}Kuratoruj pozytywne komentarze i osadz publiczna sciane opinii jednym skryptem. Pokazywane tylko zatwierdzone.
GET/POST /api/testimonialsGET /api/testimonials/public/{key}Komentarze z social mediow i rozmowy chatbota w jednym, posortowanym strumieniu do obslugi.
GET /api/inboxWspolna obsluga komentarzy z AI plus wielokrotnego uzytku gotowe odpowiedzi.
GET/POST /api/comments…GET/POST /api/reply-templates
Konfiguracja i operacje bez generowania, takie jak insighty, profil glosu,
UTM, szablony i webhooki, sa darmowe. Kredyty zuzywa praca modeli AI:
generowanie i tlumaczenie tekstu, obrazy, lektor oraz render wideo.
Autopilot pokazuje laczny szacunek przed zapisem; aktualne ceny i saldo
sprawdzisz przez GET /api/usage/prices oraz
GET /api/usage/balance.
Reference
Wszystkie endpointy wymagaja naglowka Authorization: Bearer <token>. Endpointy
oznaczone jako idempotent honoruja naglowek Idempotency-Key.
Wszystkie endpointy wymagaja naglowka Authorization: Bearer <token>. Endpointy
oznaczone jako idempotent honoruja naglowek Idempotency-Key.
Ponizsza tabela to rdzen publikacji. Pelny katalog calego API
(reels, shorts, stories, filmy, autopilot artykulow, CMS WWW,
komentarze, analityka, usage) — przygotowany tak, by mogl go uzyc
deweloper lub agent AI — znajduje sie w
docs/api-reference.md. Maszynowy kontrakt: OpenAPI pod
https://app.mumro.io/openapi.json (Swagger:
https://app.mumro.io/docs).
| Method | URL | Role | Idempotent | Opis | Statusy |
|---|---|---|---|---|---|
| POST | /api/publications |
member+ | Tak | Tworzy unified publication i rozbija ja na jeden PublishJob per target. Body: PublicationCreate. |
200, 201, 207, 401, 403, 404, 409, 422, 429 |
| GET | /api/publications/capabilities |
viewer+ | - | Macierz platforma x typ, limity caption, limity mediow i opcje story. | 200, 401, 403, 429 |
| GET | /api/publications/preview-schedule |
viewer+ | - | Najwczesniejszy wolny slot dla account_id i content_type; is_trial=true wybiera harmonogram Trial Reel. |
200, 401, 403, 404, 429 |
| GET | /api/publish-jobs |
viewer+ | - | Stronicowana kolejka i historia. Filtry: status[], platform[], account_id[], daty, sort, limit, offset. |
200, 400, 401, 403, 429 |
| GET | /api/publish-jobs/{id} |
viewer+ | - | Pojedyncza projekcja joba PublishJobRead. |
200, 401, 403, 404, 429 |
| POST | /api/publish-jobs/{id}/cancel |
member+ | - | Przenosi queued albo scheduled job do statusu canceled. | 200, 401, 403, 404, 409, 429 |
| POST | /api/publish-jobs/{id}/retry |
member+ | - | Przenosi failed albo canceled job do kolejki. | 200, 401, 403, 404, 409, 429 |
| POST | /api/publish-jobs/{id}/retry-first-comment |
member+ | - | Kolejkuje ponowienie tylko pierwszego komentarza, bez ponownej publikacji posta. | 202, 401, 402, 403, 404, 409, 429, 503 |
| PATCH | /api/publish-jobs/{id} |
member+ | - | Edytuje caption, title albo przelacza queued/scheduled job miedzy harmonogramem konta i data reczna. | 200, 400, 401, 403, 404, 409, 422, 429 |
| POST | /api/publish-jobs/{id}/move |
member+ | - | Przesuwa queued/scheduled job. Body decyduje, czy przeliczyc harmonogram, czy zostawic pozycje poza nim. | 200, 400, 401, 403, 404, 409, 422, 429 |
| POST | /api/publish-jobs/bulk/cancel |
member+ | - | Anuluje do 500 jobow. Body: { ids: number[] }. |
200, 401, 403, 422, 429 |
| POST | /api/publish-jobs/bulk/retry |
member+ | - | Ponawia do 500 jobow. Body: { ids: number[] }. |
200, 401, 403, 422, 429 |
| POST | /api/uploads/init |
member+ | - | Inicjuje presigned upload, single PUT albo multipart. | 201, 400, 401, 403, 413, 429 |
| POST | /api/uploads/{public_id}/complete |
member+ | - | Finalizuje presigned upload i oznacza MediaAsset jako ready. |
200, 400, 401, 403, 404, 429 |
| POST | /api/uploads/{public_id}/abort |
member+ | - | Anuluje upload w toku i oznacza asset jako failed. | 200, 401, 403, 404, 429 |
| POST | /api/uploads/direct |
member+ | - | Server-streamed upload do 100 MB. Obraz zwraca wygasajacy download_url i trwaly public_url. |
201, 400, 401, 403, 413, 429 |
| POST | /api/uploads/from-url |
member+ | - | Server-side fetch i upload z zewnetrznego URL z whitelisty. | 200, 401, 403, 422, 429, 502 |
| GET | /api/website-analytics/sites |
viewer+ | - | Tablica polaczonych stron, ich site_id oraz statusu integracji CMS, takze dla jednego wyniku. |
200, 401, 403, 429 |
| POST | /api/website-analytics/sites |
member+ | - | Dodaje polaczona strone. Body: { name, site_url }. |
201, 401, 403, 422, 429 |
| PUT | /api/website-analytics/sites/{site_id} |
member+ | - | Aktualizuje nazwe, URL lub aktywnosc strony. | 200, 401, 403, 404, 422, 429 |
| DELETE | /api/website-analytics/sites/{site_id} |
member+ | - | Dezaktywuje i archiwizuje polaczona strone. | 204, 401, 403, 404, 429 |
| PUT | /api/website-analytics/sites/{site_id}/cms |
member+ | - | Konfiguruje publikacje do WordPressa albo wlasnego CMS. | 200, 401, 403, 404, 422, 429 |
| POST | /api/website-analytics/sites/{site_id}/cms/test |
member+ | - | Testuje zapisana integracje CMS. | 200, 401, 403, 404, 429 |
| GET | /api/website-articles |
viewer+ | - | Lista szkicow i historii publikacji. Filtry: site_id, status, q, limit, offset. |
200, 401, 403, 429 |
| POST | /api/website-articles |
member+ | Tak | Tworzy lokalny szkic. Identyczna powtorka zwraca istniejacy artykul. | 200, 201, 400, 401, 403, 404, 422, 429 |
| GET | /api/website-articles/{article_id} |
viewer+ | - | Pobiera pojedynczy artykul WWW. | 200, 401, 403, 404, 429 |
| PUT | /api/website-articles/{article_id} |
member+ | - | Aktualizuje lokalny artykul. | 200, 401, 403, 404, 422, 429 |
| DELETE | /api/website-articles/{article_id} |
member+ | - | Archiwizuje artykul lokalnie; nie usuwa wpisu z CMS. | 204, 401, 403, 404, 429 |
| POST | /api/website-articles/{article_id}/visuals |
member+ | Zalecany | Tworzy lub odswieza grafike podsumowujaca 4:5 albo 1:1 i opcjonalna karuzele; moze ustawic wynik jako grafike glowna. | 200, 400, 401, 402, 403, 404, 422, 429, 502 |
| POST | /api/website-articles/{article_id}/publish |
member+ | - | Wysyla artykul do WordPressa lub wlasnego CMS. Blokuje nierozwiazane obrazy z X-Amz-Expires. Nalezy sprawdzic status w body. |
200, 401, 403, 404, 422, 429 |
| POST | /api/website-articles/{article_id}/social-post |
member+ | Tak | Zapisuje promocje jako draft albo kolejkuje ja w trybie now/next_slot/custom; obsluguje grafike artykulu, wygenerowana karuzele, wlasny obraz lub brak. | 200, 207, 401, 402, 403, 404, 422, 429 |
| GET | /api/api-keys |
member+ | - | Lista aktywnych kluczy API dla aktualnej organizacji. | 200, 401, 403, 429 |
| POST | /api/api-keys |
member+ | - | Generuje nowy klucz API. Token plaintext wraca tylko raz. | 201, 401, 403, 429 |
| DELETE | /api/api-keys/{key_id} |
member+ | - | Odwoluje klucz API. | 204, 401, 403, 404, 429 |
| GET | /api/analytics/posting-suggestions |
viewer+ | - | Ranking najlepszych slotow (dzien x godzina) z wlasnej historii. Etykiety pewnosci. | 200, 401, 403, 429 |
| GET | /api/analytics/hashtag-suggestions |
viewer+ | - | Hashtagi wg zaangazowania, podzielone na sprawdzone i eksperymentalne. | 200, 401, 403, 429 |
| GET | /api/analytics/recycling-candidates |
viewer+ | - | Najlepsze starsze posty warte ponownej publikacji (okno wieku, ranking). | 200, 401, 403, 429 |
| GET | /api/analytics/channel-engagement |
viewer+ | - | Zaangazowanie per kanal: posty, interakcje, obserwujacy i wskaznik zaangazowania. | 200, 401, 403, 429 |
| GET | /api/analytics/report |
viewer+ | - | Raport okresowy: totals, kanaly, top posty, najlepsze sloty, hashtagi i highlights. | 200, 401, 403, 429 |
| GET | /api/webhooks · /event-types |
member+ / viewer+ | - | Lista webhookow wychodzacych oraz katalog typow zdarzen. | 200, 401, 403, 429 |
| POST | /api/webhooks |
member+ | - | Rejestruje odbiornik HTTPS. Zdarzenia podpisane HMAC-SHA256 (X-Mumro-Signature). |
201, 401, 403, 422, 429 |
| POST | /api/webhooks/{id}/test |
member+ | - | Wysyla podpisany ping i zwraca wynik dostarczenia. |
200, 401, 403, 404, 429 |
| GET | /api/brand-voice |
viewer+ / member+ | - | Profil glosu marki: odczyt (viewer) i zapis (member). Wstrzykiwany do generatorow AI. | 200, 401, 403, 422, 429 |
| GET | /api/campaigns/settings |
viewer+ / member+ | - | Szablony UTM przestrzeni; POST /api/campaigns/tag-url taguje linki. |
200, 401, 403, 422, 429 |
| GET | /api/reply-templates |
viewer+ / member+ | - | Wielokrotnego uzytku gotowe odpowiedzi dla skrzynki komentarzy. | 200, 401, 403, 429 |
| GET | /api/inbox |
viewer+ | - | Wspolny strumien: komentarze social + rozmowy chatbota, sortowane od najnowszych. | 200, 401, 403, 429 |
| GET | /api/testimonials · /wall |
viewer+ / member+ | - | Kuratorowanie opinii i konfiguracja sciany (CRUD member+, import z komentarza). | 200, 201, 401, 403, 404, 422, 429 |
| GET | /api/testimonials/public/{key} |
public | - | Publiczna (bez auth) sciana opinii: tylko zatwierdzone pozycje, pola wyswietlania. | 200, 404 |
| GET | /api/link-in-bio/page · /links |
viewer+ / member+ | - | Konfiguracja mini-strony i przyciskow (linki tylko http/https). | 200, 201, 401, 403, 404, 422, 429 |
| GET | /api/link-in-bio/p/{key} |
public | - | Hostowana mini-strona (link-w-bio) renderowana po stronie serwera. | 200, 404 |
Schemas
Zrodlem kontraktu jest app.schemas.publication.PublicationCreate. Opcje wspolne
przekazuj przez common_content.platform_options, a opcje pojedynczego targetu przez
overrides[account_id].platform_options.
{
"publication_type": "post|story|reel|film",
"targets": ["<account_id>"],
"common_content": {
"caption": "Hello world",
"hashtags": ["smm", "automation"],
"media_asset_ids": ["<media_asset_id>"],
"subtitle_asset_id": "<srt_media_asset_id>",
"subtitle_locale": "pl_PL",
"first_comment_text": "Prepared first comment for IG/FB post or reel",
"title": "optional (required for film)",
"description": "optional",
"cover": { "kind": "frame_at_seconds", "t": 1.5 },
"platform_options": {
"youtube": { "privacy": "unlisted", "tags": ["api"] },
"tiktok": { "privacy_level": "SELF_ONLY", "disable_comment": true },
"x": { "content_type": "thread", "thread": ["tweet 1", "tweet 2"] },
"linkedin": { "content_type": "article", "url": "https://example.com" }
}
},
"overrides": {
"<account_id>": {
"caption_override": "...",
"hashtags_override": ["..."],
"media_override": ["<media_asset_id>"],
"story_options": { "link_sticker_url": "https://example.com" },
"cover_override": { "kind": "asset", "asset_id": 123 },
"title_override": "...",
"description_override": "...",
"subtitle_asset_id": "<srt_media_asset_id>",
"subtitle_locale": "pl_PL",
"first_comment_text": "Prepared first comment for this target",
"tags_override": ["yt", "tags"],
"share_to_feed": true,
"fb_title": "Facebook reel title",
"fb_comment_text": "Legacy Facebook-only first comment alias",
"is_trial": true,
"platform_options": { "privacy": "private" },
"scheduled_at": "2026-07-01T15:00:00+02:00",
"target_ig": true,
"target_fb": false
}
},
"schedule_mode": "draft|now|next_slot|custom",
"scheduled_at": "2026-07-01T15:00:00+02:00",
"scheduled_at_per_target": {
"<account_id>": "2026-07-01T15:00:00+02:00"
}
}
Gdy schedule_mode jest pominiete albo ma wartosc next_slot,
API uzywa harmonogramu konta i zapisuje job jako schedule_source="auto".
custom wymaga scheduled_at i zapisuje manual.
now publikuje natychmiastowo poza harmonogramem, tez jako manual.
Dla posta draft zapisuje edytowalny szkic bez joba workera.
schedule_mode | Znaczenie | schedule_source |
|---|---|---|
omitted / next_slot | Uzyj harmonogramu konta. | auto |
custom | Uzyj podanej daty publikacji. | manual |
now | Wyslij job do publikacji od razu. | manual |
GET /api/publish-jobs pokazuje schedule_source. Wartosci
auto moga byc przeliczane przez harmonogram. Wartosci manual
sa poza harmonogramem i nie sa ruszane przez jego przeliczenia.
Gdy auto ma scheduled_at=null, job nadal nalezy do harmonogramu
i nie jest publikowany natychmiastowo.
GET /api/publications/preview-schedule?account_id=10&content_type=reel&is_trial=true
Gdy is_trial jest pominiete, API uzywa domyslnej wartosci
ig_trial_reels konta. Odpowiedz zwraca rozstrzygniete is_trial
i tablice warnings. Kod
trial_reel_schedule_requires_is_trial oznacza, ze zwykly Reel nie ma slotu,
ale konto ma dostepny slot Trial Reel.
Dla postow, Stories i Reels jobs[].job_id z POST /api/publications
jest tym samym numerem co items[].id z listy i parametr {id} tras
detail/cancel/retry/move/patch. Dla filmu job_id jest identyfikatorem filmu
obslugiwanym przez osobna powierzchnie /api/films/*.
media_asset_id jest osobnym identyfikatorem zasobu mediowego.
Automatyczny scheduler jest globalnie dlawiony: jezeli kilka pozycji jest gotowych w tym samym ticku, Mumro wrzuca do publikacji najwyzej jedna i zostawia pozostale na kolejne przebiegi. Scheduler czeka tez, gdy publikacja juz trwa albo kolejka publikacji ma zaleglosc, wiec opozniony harmonogram nie powinien wypchnac wielu postow naraz.
PATCH /api/publish-jobs/123
{
"schedule_source": "auto"
}
PATCH /api/publish-jobs/123
{
"scheduled_at": "2026-07-15T18:00:00+02:00"
}
POST /api/publish-jobs/123/move
{
"position": 1,
"schedule_policy": "shift_schedule"
}
schedule_policy="keep_time" zmienia kolejnosc listy, oznacza przesuwany job
jako manual i nie zmienia dat innych jobow.
| Platform key | Common fields |
|---|---|
youtube | title, description, tags, category / category_id, privacy / privacy_status |
tiktok | content_type, privacy_level, disable_duet, disable_comment, disable_stitch, cover_ms, cover_index |
x / twitter | content_type, thread |
linkedin | content_type, url, title, visibility |
instagram_facebook | fb_title, first_comment_text, fb_comment_text, is_trial; subtitle_asset_id / subtitle_locale dla napisow Facebook Reel; uzyj target_ig / target_fb dla fan-out IG vs FB. share_to_feed wraca w capabilities jako unavailable=true i nie jest wykonywane przez adapter publikacji. |
Dla targetow Instagram/Facebook pola fb_title, first_comment_text,
fb_comment_text i is_trial mozna przekazac bezposrednio w overrides[account_id] albo
wewnatrz overrides[account_id].platform_options. Pola bezposrednie wygrywaja,
jesli oba warianty sa obecne.
first_comment_text dodaje przygotowany pierwszy komentarz po udanej publikacji
posta albo rolki Instagram/Facebook. Mozna go podac w
common_content.first_comment_text, overrides[account_id].first_comment_text
albo w odpowiednim platform_options. Wyslanie komentarza jest best-effort:
jego stan widac jako first_comment_status i first_comment_results.
Blad komentarza nie oznacza nieudanej publikacji; mozna ponowic tylko komentarz przez
POST /api/publish-jobs/{id}/retry-first-comment. fb_comment_text
zostaje jako zgodny wstecz alias tylko dla Facebooka.
Dla obrazow upload zwraca trwaly public_url oraz krotko wazny,
podpisany download_url. W HTML artykulu zapisuj tylko
public_url; download_url sluzy do natychmiastowego podgladu.
Publikacja i planowanie sa blokowane, jesli po normalizacji pozostaje obraz
z X-Amz-Expires. Dla grafiki glownej uzyj
featured_image_asset_id, featured_image_alt i opcjonalnego
featured_image_caption; odpowiedz zawiera trwaly
featured_image_url.
Napisy SRT sa natywnymi napisami Meta/Facebook dla wideo. Uploaduj plik
.srt jako asset subtitle i przekaz jego numeryczne
id jako subtitle_asset_id. Pole jest wykonywane tylko dla
powierzchni Facebook Reel (target_fb=true). Instagram Reels Graph API
nie przyjmuje plikow SRT; target tylko IG z subtitle_asset_id zostanie
odrzucony z media_asset_invalid. subtitle_locale domyslnie
ma wartosc pl_PL i musi miec format Meta, np. pl_PL
albo en_US.
Zeby uzyc tego samego MP4 na Instagramie i Facebooku, uploaduj plik raz przez
POST /api/uploads/direct albo presigned upload i przekaz zwrocone numeryczne
id w common_content.media_asset_ids. Nie tworz osobnych uploadow per
platforma, chyba ze pliki naprawde sie roznia.
{
"publication_id": "<uuid5 of (organization, idempotency_key)>",
"request_id": "<X-Request-Id>",
"jobs": [
{
"target_id": "<account_id>",
"job_id": "<queue_job_id_or_film_job_id | null>",
"status": "draft|scheduled|queued|succeeded|failed",
"schedule_source": "auto|manual|null",
"scheduled_at": "ISO-8601 | null",
"error_code": "string | null",
"error_message": "string | null"
}
],
"summary": { "error_code": "all_targets_failed" }
}
Odpowiedzi JSON deklaruja Content-Type: application/json; charset=utf-8.
Nieznana sciezka /api/* zwraca JSON
404 api_route_not_found i nie przechodzi do fallbacku SPA.
Live reference
Aktualna macierz platforma x typ publikacji i limity mediow sa wystawione przez
GET /api/publications/capabilities. Poniewaz macierz zmienia sie wraz z platformami
i limitami, kanoniczna odpowiedz powinna byc pobierana runtime.
Token sluzy tylko do tego requestu w przegladarce i nie jest zapisywany.
{
"platforms": {
"instagram_facebook": {
"supported_types": ["post", "reel", "story"],
"caption_limits": { "post": 2200, "reel": 2200, "story": 0 },
"platform_options": {
"content_type": {
"type": "enum",
"values": ["auto", "image", "video"],
"supported_on_create": true,
"supported_on_edit": false,
"legacy_only": false,
"unavailable": false
},
"fb_title": {
"type": "string",
"max_length": 255,
"supported_on_create": true,
"supported_on_edit": true,
"legacy_only": false,
"unavailable": false,
"accepted_locations": [
"common_content.platform_options.instagram_facebook.fb_title",
"overrides.*.platform_options.fb_title",
"overrides.*.fb_title"
]
},
"first_comment_text": {
"type": "string",
"max_length": 2000,
"surface": "instagram_facebook_post_reel",
"supported_on_create": true,
"supported_on_edit": false,
"legacy_only": false,
"unavailable": false,
"accepted_locations": [
"common_content.first_comment_text",
"common_content.platform_options.instagram_facebook.first_comment_text",
"overrides.*.first_comment_text",
"overrides.*.platform_options.first_comment_text"
],
"reason": "Posted best-effort after an Instagram/Facebook post or reel is published. Comment failure does not fail the publication."
},
"is_trial": {
"type": "boolean",
"supported_on_create": true,
"supported_on_edit": true,
"legacy_only": false,
"unavailable": false,
"accepted_locations": [
"common_content.platform_options.instagram_facebook.is_trial",
"overrides.*.platform_options.is_trial",
"overrides.*.is_trial"
]
},
"subtitle_asset_id": {
"type": "integer",
"asset_type": "subtitle",
"format": "srt",
"surface": "facebook_reel",
"supported_on_create": true,
"supported_on_edit": false,
"legacy_only": false,
"unavailable": false,
"accepted_locations": [
"common_content.subtitle_asset_id",
"overrides.*.subtitle_asset_id"
],
"reason": "Executed only for the Facebook Reel/video surface. Instagram Reels Graph API does not accept SRT caption files."
},
"subtitle_locale": {
"type": "string",
"default": "pl_PL",
"format": "meta_locale",
"surface": "facebook_reel",
"supported_on_create": true,
"supported_on_edit": false,
"legacy_only": false,
"unavailable": false,
"accepted_locations": [
"common_content.subtitle_locale",
"overrides.*.subtitle_locale"
]
},
"share_to_feed": {
"type": "boolean",
"supported_on_create": false,
"supported_on_edit": false,
"legacy_only": false,
"unavailable": true,
"reason": "Not currently executed by the Instagram/Facebook publishing adapter."
}
}
}
},
"media_limits": {
"post": { "types": ["image/jpeg", "image/png", "image/webp"], "max_mb": 10, "count_max": 10 },
"reel": { "types": ["video/mp4", "video/quicktime"], "max_mb": 500, "count_max": 1 }
},
"story_options": {
"instagram_facebook": {
"link_sticker_url": { "type": "url", "max_length": 2000 }
}
}
}
Kazda opcja w platform_options ma metadane wykonania:
supported_on_create, supported_on_edit, legacy_only
i unavailable. Dla Instagram/Facebook is_trial,
fb_title, first_comment_text i fb_comment_text mozna wyslac bezposrednio w
overrides[account_id] albo w overrides[account_id].platform_options.
first_comment_text mozna tez podac raz w common_content.first_comment_text;
komentarz jest dodawany best-effort po udanym poscie albo rolce IG/FB.
Examples
Zastap smm_REPLACE_ME realnym kluczem API. Requesty kieruj do
https://app.mumro.io.
Najpierw pobierz site_id, potem utworz lokalny szkic z kluczem idempotencji,
a publikacje wykonaj osobnym requestem. Po publikacji sprawdz status w body.
curl -X POST https://app.mumro.io/api/website-articles \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"site_id": 12,
"title": "Artykul z API",
"content_html": "<h2>Wprowadzenie</h2><p>Tresc artykulu.</p>",
"featured_image_asset_id": 41,
"featured_image_alt": "Opis grafiki glownej",
"featured_image_caption": "Opcjonalny podpis",
"metadata_json": {
"source": "content-agent",
"source_record_id": "agent-job-123"
}
}'
curl -X POST https://app.mumro.io/api/website-articles/123/publish \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{"remote_status":"publish"}'
published = requests.post(
f"https://app.mumro.io/api/website-articles/{article_id}/publish",
headers={"Authorization": f"Bearer {os.environ['SMM_API_KEY']}"},
json={"remote_status": "publish"},
timeout=30,
)
published.raise_for_status()
result = published.json()
if result["status"] == "failed":
raise RuntimeError(result["last_publish_error"])
if result["status"] != "published":
raise RuntimeError(f"Unexpected status: {result['status']}")
W Windows PowerShell 5.1 koduj JSON jawnie jako bajty UTF-8 i ustaw timeout.
Jesli starszy host nadal zawisa, uzyj curl.exe albo PowerShell 7.
$json = @{
site_id = 12
title = "Artykul z polskimi znakami"
content_html = "<p>Tresc artykulu.</p>"
} | ConvertTo-Json -Depth 20 -Compress
$body = [Text.Encoding]::UTF8.GetBytes($json)
Invoke-RestMethod `
-Method Post `
-Uri "https://app.mumro.io/api/website-articles" `
-Headers @{ Authorization = "Bearer $env:SMM_API_KEY"; "Idempotency-Key" = [guid]::NewGuid().ToString() } `
-ContentType "application/json; charset=utf-8" `
-Body $body `
-TimeoutSec 60
curl -X POST https://app.mumro.io/api/publications \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-d '{
"publication_type": "post",
"targets": [42, 43],
"common_content": {
"caption": "Hello from the API",
"hashtags": ["smm", "automation"],
"media_asset_ids": [1234]
},
"schedule_mode": "now"
}'
import os, uuid, requests
resp = requests.post(
"https://app.mumro.io/api/publications",
headers={
"Authorization": f"Bearer {os.environ['SMM_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"publication_type": "post",
"targets": [42, 43],
"common_content": {
"caption": "Hello from Python",
"hashtags": ["smm", "automation"],
"media_asset_ids": [1234],
},
"schedule_mode": "now",
},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
const idempotencyKey = crypto.randomUUID();
const resp = await fetch("https://app.mumro.io/api/publications", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMM_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey,
},
body: JSON.stringify({
publication_type: "post",
targets: [42, 43],
common_content: {
caption: "Hello from Node",
hashtags: ["smm", "automation"],
media_asset_ids: [1234],
},
schedule_mode: "now",
}),
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());
curl -X POST https://app.mumro.io/api/publications \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-d '{
"publication_type": "reel",
"targets": [55],
"common_content": {
"caption": "Reel for next slot",
"media_asset_ids": [9001]
},
"schedule_mode": "next_slot"
}'
Uploaduj MP4 raz i uzyj numerycznego id z odpowiedzi jako
common_content.media_asset_ids[0]. POST /api/uploads/direct
jest dla plikow do 100 MB; dla wiekszych wideo uzyj presigned upload.
curl -X POST https://app.mumro.io/api/uploads/direct \
-H "Authorization: Bearer smm_REPLACE_ME" \
-F "asset_type=video" \
-F "file=@role-playing-life-01.mp4;type=video/mp4"
{
"asset_id": "4f4d9f1b-ff4e-4a2e-84db-9e6ec1a7dfc0",
"id": 9001,
"file_size_bytes": 48239122,
"download_url": "https://..."
}
Opcjonalne napisy Facebook Reel uploaduj jako osobny asset
subtitle. Uzyj zwroconego numerycznego id
tylko w override targetu Facebookowego. Instagram Reels Graph API
nie przyjmuje plikow SRT.
curl -X POST https://app.mumro.io/api/uploads/direct \
-H "Authorization: Bearer smm_REPLACE_ME" \
-F "asset_type=subtitle" \
-F "file=@role-playing-life-01.pl_PL.srt;type=application/x-subrip"
{
"asset_id": "0ca8f11e-b0fe-44d2-bc1c-3ba3b9f1e9be",
"id": 9002,
"file_size_bytes": 2188,
"download_url": "https://..."
}
curl -X POST https://app.mumro.io/api/publications \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"publication_type": "reel",
"targets": [19, 23],
"common_content": {
"caption": "Role Playing Life",
"media_asset_ids": [9001],
"first_comment_text": "Full story and links in the comments."
},
"overrides": {
"19": {
"target_ig": true,
"target_fb": false,
"is_trial": true
},
"23": {
"target_ig": false,
"target_fb": true,
"fb_title": "Role Playing Life",
"subtitle_asset_id": 9002,
"subtitle_locale": "pl_PL"
}
},
"schedule_mode": "now"
}'
curl -X POST https://app.mumro.io/api/publications \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"publication_type": "post",
"targets": [42, 77, 88],
"common_content": {
"caption": "Launch update",
"media_asset_ids": [1234, 1235],
"platform_options": {
"x": {
"content_type": "thread",
"thread": ["Launch update", "More details in the link"]
},
"linkedin": {
"content_type": "article",
"url": "https://example.com/launch",
"title": "Launch update"
},
"tiktok": {
"content_type": "carousel",
"privacy_level": "SELF_ONLY",
"disable_comment": false
}
}
},
"overrides": {
"77": {
"caption_override": "LinkedIn-specific copy",
"platform_options": { "visibility": "PUBLIC" }
}
},
"schedule_mode": "now"
}'
curl -X POST https://app.mumro.io/api/publications \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"publication_type": "film",
"targets": [201],
"common_content": {
"title": "API release walkthrough",
"description": "Long-form release video",
"media_asset_ids": [555],
"platform_options": {
"youtube": {
"privacy": "unlisted",
"category": "28",
"tags": ["mumro", "api", "release"]
}
}
},
"schedule_mode": "custom",
"scheduled_at": "2026-07-15T18:00:00+02:00"
}'
curl -X POST https://app.mumro.io/api/publications \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{
"publication_type": "story",
"targets": [101],
"common_content": { "media_asset_ids": [7777] },
"overrides": {
"101": {
"story_options": { "link_sticker_url": "https://example.com/landing" }
}
},
"schedule_mode": "now"
}'
curl -G https://app.mumro.io/api/publish-jobs \
-H "Authorization: Bearer smm_REPLACE_ME" \
--data-urlencode "status=queued" \
--data-urlencode "status=scheduled" \
--data-urlencode "platform=instagram_facebook" \
--data-urlencode "limit=20" \
--data-urlencode "offset=0"
curl -X PATCH https://app.mumro.io/api/publish-jobs/123 \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{ "schedule_source": "auto" }'
curl -X PATCH https://app.mumro.io/api/publish-jobs/123 \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{ "scheduled_at": "2026-07-15T18:00:00+02:00" }'
curl -X POST https://app.mumro.io/api/publish-jobs/123/move \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{ "position": 1, "schedule_policy": "shift_schedule" }'
curl -X POST https://app.mumro.io/api/publish-jobs/123/move \
-H "Authorization: Bearer smm_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{ "position": 1, "schedule_policy": "keep_time" }'
curl -X POST https://app.mumro.io/api/publish-jobs/123/cancel \
-H "Authorization: Bearer smm_REPLACE_ME"
curl -X POST https://app.mumro.io/api/publish-jobs/123/retry \
-H "Authorization: Bearer smm_REPLACE_ME"
Cykliczne karuzele Instagram
Autopilot karuzel
Mumro moze regularnie zebrac zrodla z internetu lub wlasnego portalu, przygotowac pionowa karuzele, opis i hashtagi, a potem zapisac szkic, uzyc najblizszego slotu albo opublikowac.
Ustal serie
Wybierz temat, kanal Instagram, jezyk, ton oraz cykl od 1 do 90 dni.
Wybierz zrodlo
Uzyj profilu RSS i domen, wyszukiwarki, najnowszych artykulow portalu, jednego artykulu albo briefu evergreen.
Najpierw podejrzyj
Podglad zawsze tworzy szkic, nie publikuje i nie przesuwa kolejnego terminu cyklu.
Artykuly, rolki i karuzele korzystaja z tych samych profili RSS/Atom, oficjalnych i preferowanych domen oraz progow jakosci. Gotowy profil AI mozna dodac jednym przyciskiem w Ustawieniach - Zrodla informacji, edytowac, duplikowac i sprawdzic bez generowania tresci. Test pokazuje osiagniete progi oraz konkretne daty i linki do publikacji. Profil z RSS dziala bez Tavily; Brave Search, SerpAPI albo Tavily moze rozszerzyc wyniki w trybie hybrydowym. Kazdy adres RSS jest osobnym torem researchu, nawet gdy kilka kanalow pochodzi z tej samej domeny.
Autopilot renderuje wlasne slajdy 1080 x 1350 albo kwadratowe 1080 x 1080, moze wygenerowac okladke AI albo wykorzystac grafiki wyrozniajace artykulow z aktywnej przestrzeni. Slajdy tematyczne moga dostac do czterech bezpiecznie pobranych obrazow dopasowanych zrodel, a badge z liczba lub nazwa modelu pojawia sie tylko wtedy, gdy fakt nie wystepuje juz w tekscie. Brak obrazu lub blad pliku uruchamia bezpieczny szablon i nie przerywa generowania. Nie kopiuje dowolnych zdjec, nie wykonuje obcego HTML ani automatycznych screenshotow stron. Artykul mozna przekazac do karuzeli bezposrednio z edytora Artykuly WWW i sprawdzic w podgladzie przed publikacja. Pelna instrukcja znajduje sie w
docs/social-autopilot.md.