Czytaj i zapisuj leady, buduj kampanie, odbieraj odpowiedzi i podłącz własne narzędzia. JSON, klucze z zakresami, stronicowanie kursorem i podpisane webhooki. API jest w planach Pro, Business i Agencja (także w 14-dniowym okresie próbnym).
Cały opis API w formacie OpenAPI 3.1 jest pod adresem https://outreachpilot.pl/api/v1/openapi.json. Zaimportujesz go w Postmanie, Insomnii albo generatorze klienta. Wszystkie daty są w ISO 8601 (UTC), a nazwy pól w snake_case.
Klucze i zakresy (scope)
Każde żądanie wymaga nagłówka Authorization: Bearer op_live_…. Klucz jest powiązany z Twoim kontem, ma nazwę, zakresy i opcjonalną datę wygaśnięcia. Możesz mieć do 10 aktywnych kluczy (osobny na każde narzędzie), odwołać każdy w sekundę i zobaczyć, kiedy był ostatnio użyty.
Zakres
Co pozwala
leads:read
Czytanie leadów. Twoja baza firm i kontaktów oraz tagi (tylko odczyt)
leads:write
Edycja leadów. Dodawanie, aktualizacja, statusy, tagowanie, wzbogacanie i import
leads:delete
Usuwanie leadów. Trwałe kasowanie - akcja nieodwracalna Operacja nieodwracalna.
leads:scrape
Wyszukiwanie firm. Wyszukiwanie firm w Google Maps, PKT, OSM i Panoramie: zapisuje leady i zużywa miesięczny limit
campaigns:read
Czytanie kampanii. Lista kampanii, sekwencje wiadomości, statystyki i historia wysyłki
Czytanie inboxu. Odpowiedzi od leadów (pełna treść) i propozycje agentów AI
analytics:read
Statystyki kampanii. Wyniki kampanii i kroków: wysłane, otwarcia, odpowiedzi, zwroty (tylko odczyt)
webhooks:read
Czytanie webhooków. Lista Twoich webhooków (bez sekretów)
webhooks:write
Zarządzanie webhookami. Dodawanie i usuwanie webhooków; sekret pokazujemy jeden raz przy tworzeniu. Zdarzenia lead.* i email.* zawierają adresy e-mail i nazwy firm, więc ich subskrypcja wymaga też leads:read
Nazwy zakresów są te same co w naszym konektorze MCP dla asystentów AI, więc jeden słownik obejmuje oba sposoby dostępu. Zasada najmniejszych uprawnień: odczyt nie pozwala na zapis, zapis nie obejmuje kasowania.
Klucz API a MCP. API jest dla Twoich integracji i skryptów. Jeśli chcesz, żeby asystent AI (Claude, ChatGPT) pracował na Twoim koncie, użyj konektora MCP.
Plany i limity
Plan
Dostęp do API
Limit żądań na klucz
Free
brak (403 z informacją o planie)
-
Starter
brak (403 z informacją o planie)
-
Pro (także okres próbny)
tak
60 na minutę
Business
tak
120 na minutę
Agencja
tak
300 na minutę
Plan sprawdzamy przy każdym żądaniu: po spadku planu klucze przestają działać (403 plan_upgrade_required), ale zostają zapisane i wracają do pracy po powrocie na plan z API. Każda odpowiedź ma nagłówki X-RateLimit-Limit, X-RateLimit-Remaining i X-RateLimit-Reset (sekundy Unix). Po przekroczeniu limitu dostajesz 429 z nagłówkiem Retry-After.
Leady z API zużywają ten sam miesięczny limit leadów co aplikacja (zapis jest atomowy, równoległe żądania nie przekroczą limitu). Duplikaty nie kosztują. Wyszukiwarka firm (POST /leads/search) liczy limit tak samo jak w aplikacji.
Listy są od najnowszych. Parametr limit (1-100, domyślnie 25) ustala rozmiar strony, a next_cursor z odpowiedzi podajesz jako cursor w kolejnym żądaniu. Kursor jest nieprzezroczysty i odporny na dopisywanie nowych rekordów w trakcie pobierania (nie gubi ani nie dubluje wierszy).
JavaScript
// Pobranie wszystkich leadów ze statusem "zainteresowany" (strony po 100)
const wait = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1000))
let cursor = null
const all = []
for (;;) {
const url = new URL("https://outreachpilot.pl/api/v1/leads")
url.searchParams.set("status", "zainteresowany")
url.searchParams.set("limit", "100")
if (cursor) url.searchParams.set("cursor", cursor)
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.OUTREACHPILOT_API_KEY}` } })
if (res.status === 429) { await wait(Number(res.headers.get("retry-after") ?? 5)); continue } // ponów TĘ SAMĄ stronę
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const page = await res.json()
all.push(...page.data)
if (!page.pagination.next_cursor) break
cursor = page.pagination.next_cursor
}
Błędy
Błąd zawsze ma ten sam kształt, a request_id podaj przy zgłaszaniu problemu:
403
{
"error": {
"code": "plan_upgrade_required",
"message": "API jest dostępne od planu Pro (…)",
"details": {
"current_plan": "starter",
"required_plan": "pro"
},
"request_id": "req_3f9a1c2b7d8e4f5a6b7c8d9e"
}
}
Kod
HTTP
Znaczenie
invalid_request
400
Nieprawidłowe żądanie: zepsuty JSON lub kursor (400), zły Content-Type (415), za duże ciało (413); także reguły biznesowe kampanii (422).
validation_error
422
Dane nie przeszły walidacji; szczegóły w `details`.
missing_api_key
401
Brak nagłówka Authorization: Bearer op_live_…
invalid_api_key
401
Klucz nie istnieje albo ma zły format.
api_key_revoked
401
Klucz został odwołany.
api_key_expired
401
Klucz wygasł.
account_inactive
401
Konto jest nieaktywne lub zablokowane.
plan_upgrade_required
403
Plan konta nie obejmuje API (Starter, Free). Odpowiedź zawiera informacje o planie.
insufficient_scope
403
Klucz nie ma wymaganego zakresu (scope).
not_found
404
Nie ma takiego zasobu (albo nie należy do Twojego konta).
conflict
409
Konflikt stanu, np. niedozwolona zmiana statusu kampanii.
duplicate_lead
409
Lead z takim adresem e-mail (lub tą samą firmą) już jest w bazie.
confirmation_required
409
Uruchomienie wymaga potwierdzenia ostrzeżeń (`acknowledge_warnings: true`).
lead_limit_reached
402
Wyczerpany miesięczny lub dzienny limit leadów.
rate_limit_exceeded
429
Za dużo żądań. Zobacz nagłówek Retry-After.
upstream_unavailable
503
Usługa zależna (np. wyszukiwarka firm) chwilowo niedostępna. Nic nie zapisano.
service_unavailable
503
Usługa chwilowo niedostępna. Spróbuj ponownie.
internal_error
500
Nieoczekiwany błąd serwera.
Endpointy
Adres bazowy: https://outreachpilot.pl/api/v1. Każdy endpoint pokazuje wymagany zakres, parametry, przykład curl i odpowiedź. Operacje, które wysyłają prawdziwe maile (start kampanii) albo zużywają limit (zapis leadów, wyszukiwarka), są opisane wprost.
Konto
get/api/v1/medowolny klucz
Konto, plan, limity i zużycie
Zwraca właściciela klucza: plan, limity (leady, wysyłka, limit żądań API), bieżące zużycie oraz metadane samego klucza (nazwa, prefiks, zakresy, wygaśnięcie). Nie wymaga żadnego zakresu: dobry pierwszy test klucza.
Lista klientów konta agencji (plan Business: do 3, Agencja bez limitu) plus `default` = „Moja firma” (dane bez klienta). ID klienta podaj jako `workspace_id` w filtrach list (`GET /leads`, `GET /campaigns`) i w żądaniach zapisu (`POST /leads`, `/leads/bulk`, `/leads/search`, `/campaigns`). Bez `workspace_id` listy obejmują całe konto, a nowe dane trafiają do „Mojej firmy”. Limity i rachunek są wspólne dla konta. Nie wymaga zakresu.
Dodaje jeden lead. Zapis jest atomowy i zużywa miesięczny limit leadów (tak jak w aplikacji). Duplikat (ten sam e-mail, strona, telefon albo nazwa i miasto) zwraca 409 `duplicate_lead` i nic nie kosztuje. Wymagane: `company_name` lub `email`.
Edycja leadów: Dodawanie, aktualizacja, statusy, tagowanie, wzbogacanie i import
Pola ciała żądania
Pole (JSON)
Typ
Opis
company_name
string
Nazwa firmy.
first_name
string
Imię.
last_name
string
Nazwisko.
email
string
Adres e-mail (unikalny w Twojej bazie).
phone
string
Telefon.
job_title
string
Stanowisko.
company_city
string
Miasto.
company_industry
string
Branża.
company_website
string
Strona WWW firmy.
company_address
string
Adres.
company_nip
string
NIP.
company_regon
string
REGON.
company_voivodeship
string
Województwo.
company_pkd
string
Kod PKD.
notes
string
Notatki.
tags
array<string>
Tagi (maks. 20).
workspace_id
string
Klient agencji, do ktorego trafia zapis (ID z `GET /workspaces`, klient musi byc aktywny). Bez pola: "Moja firma".
Błędy tej operacji: validation_error (422), duplicate_lead (409), lead_limit_reached (402). Wspólne dla wszystkich: 401, 403, 429.
post/api/v1/leads/bulkzakres leads:write
Dodaj wiele leadów (do 500)
Importuje do 500 leadów w jednym żądaniu. Każdy element jest walidowany osobno: błędny trafia do `rejected`, duplikat do `duplicates`, reszta jest zapisywana do wyczerpania limitu (nadmiar w `omitted_by_limit`). Odpowiedź 200 nawet przy częściowym sukcesie; wynik per indeks.
Edycja leadów: Dodawanie, aktualizacja, statusy, tagowanie, wzbogacanie i import
Pola ciała żądania
Pole (JSON)
Typ
Opis
leads*
array<any>
Lista leadów (1-500). Każdy element ma pola jak w POST /leads; błędny element nie psuje reszty.
tag
string
Tag dodawany do wszystkich zapisanych leadów.
workspace_id
string
Klient agencji, do ktorego trafia zapis (ID z `GET /workspaces`, klient musi byc aktywny). Bez pola: "Moja firma".
Błędy tej operacji: validation_error (422), lead_limit_reached (402). Wspólne dla wszystkich: 401, 403, 429.
post/api/v1/leads/searchzakres leads:scrape
Wyszukaj firmy i zapisz jako leady
Wyszukiwarka firm (Google Maps, PKT, OpenStreetMap, Panorama Firm) przez ten sam potok co aplikacja: dedupe, bramka jakości (miasto, kontakt, weryfikacja adresu) i ATOMOWE naliczenie limitu. Znalezione nowe firmy są zapisywane jako leady; te, które już masz, nie zużywają limitu. Zapytanie trwa zwykle 30-250 s, więc ustaw długi timeout klienta (min. 300 s). Wymaga zakresu `leads:scrape`.
Wyszukiwanie firm: Wyszukiwanie firm w Google Maps, PKT, OSM i Panoramie: zapisuje leady i zużywa miesięczny limit
Pola ciała żądania
Pole (JSON)
Typ
Opis
query*
string
Branża lub fraza, np. `hydraulik`.
city
string
Miasto, np. `Kraków`.
sources
array<"google_maps" | "pkt" | "osm" | "panorama">
Źródła. Domyślnie wszystkie cztery.
limit
integer (min 1, max 50)
Ile firm maksymalnie (1-50). Przycinane do pozostałego limitu leadów.
mode
"auto" | "no_website" | "with_website"
`no_website` = tylko firmy z potwierdzonym brakiem strony.
require_email
boolean
Zapisuj tylko firmy z adresem e-mail.
filter_has_phone
boolean
Tylko firmy z telefonem.
filter_min_rating
number (min 0, max 5)
Minimalna ocena w Google Maps (0-5).
workspace_id
string
Klient agencji, do ktorego trafia zapis (ID z `GET /workspaces`, klient musi byc aktywny). Bez pola: "Moja firma".
Błędy tej operacji: not_found (404). Wspólne dla wszystkich: 401, 403, 429.
patch/api/v1/leads/{id}zakres leads:write
Zmień lead
Częściowa aktualizacja pól, statusu i tagów (`tags` zastępuje całą listę). `null` czyści wartość. Zmiana `status` wysyła webhook `lead.status_changed` (`changed_by: api`).
Edycja leadów: Dodawanie, aktualizacja, statusy, tagowanie, wzbogacanie i import
Tworzy kampanię w statusie `szkic` z pierwszymi leadami (do 200; kolejne dodasz przez `POST /campaigns/{id}/leads`): NIC nie jest wysyłane. Uruchomienie to osobne wywołanie `POST /campaigns/{id}/status`. Te same walidacje i limity planu co w aplikacji (limit kampanii, poprawność skrzynki, pomijanie leadów odrzuconych i wypisanych).
Nazwa kampanii. Bez niej powstaje nazwa automatyczna (branża, miasto, data).
lead_ids*
array<string>
Leady do kampanii (1-200). Resztę dodaj przez POST /campaigns/{id}/leads (do 1000 na żądanie). Odrzuceni, z bounce'em i wypisani są pomijani.
email_account_id
string
Skrzynka nadawcza. Domyślnie pierwsza podłączona.
steps*
array<object>
Sekwencja wiadomości (1-10 kroków).
daily_limit
integer (min 1, max 200)
Maks. wiadomości dziennie z tej kampanii.
sending_window_start
string
Początek okna wysyłki (HH:MM, czas Warszawy).
sending_window_end
string
Koniec okna wysyłki (HH:MM).
track_opens
boolean
track_clicks
boolean
workspace_id
string
Klient agencji, do którego należy kampania (ID z `GET /workspaces`). Bez pola kampania dziedziczy klienta po swoich leadach (leady z różnych klientów to błąd 422). Leady i skrzynka muszą być tego klienta.
Przykład (curl)
curl -X POST "https://outreachpilot.pl/api/v1/campaigns" \
-H "Authorization: Bearer $OUTREACHPILOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Hydraulicy Kraków",
"lead_ids": [
"0b6f2c1e-8a41-4f7e-9d3a-5c1f2a7b9e10"
],
"steps": [
{
"subject": "Pytanie o instalacje w {{firma}}",
"body": "Dzień dobry {{imie}}, ..."
},
{
"subject": "Re: Pytanie o instalacje w {{firma}}",
"body": "Wracam do tematu ...",
"delay_days": 3
}
],
"daily_limit": 20
}'
Dodaje leady do istniejącej kampanii (do 1000). Pomija leady już obecne, odrzucone, z bounce'em i wypisane. Gdy kampania jest aktywna, nowe leady od razu wchodzą do wysyłki.
`start` uruchamia szkic, `pause` wstrzymuje aktywną, `resume` wznawia wstrzymaną. Start i wznowienie WYSYŁAJĄ PRAWDZIWE MAILE. Jeśli są ostrzeżenia (warmup, DNS, limit domeny), odpowiedź ma kod `confirmation_required`; ponów żądanie z `acknowledge_warnings: true`, gdy świadomie chcesz kontynuować. Powtórzenie tej samej akcji jest bezpieczne (`changed: false`).
Sumy i wskaźniki kampanii oraz wyniki per krok. Odpowiedzi liczone są jako odpowiedzi LUDZI (zwroty i autorespondery systemowe wykluczone). Otwarcia są orientacyjne (Apple Mail je zawyża), dlatego wskaźnikiem jakości jest `reply_rate`.
Statystyki kampanii: Wyniki kampanii i kroków: wysłane, otwarcia, odpowiedzi, zwroty (tylko odczyt)
Błędy tej operacji: not_found (404). Wspólne dla wszystkich: 401, 403, 429.
Odpowiedzi
get/api/v1/replieszakres inbox:read
Odpowiedzi od leadów
Odpowiedzi LUDZI na Twoje wiadomości, od najnowszych. Zwroty (bounce, NDR, autorespondery systemowe) nie trafiają na listę. Domyślnie zwracamy początek odpowiedzi (`snippet`); pełna treść tylko z `include_text=true`.
Czytanie inboxu: Odpowiedzi od leadów (pełna treść) i propozycje agentów AI
Parametry
Parametr
Typ
Opis
limitquery
integer (min 1, max 100)
Rozmiar strony (1-100, domyślnie 25).
cursorquery
string
Kursor następnej strony: wartość `next_cursor` z poprzedniej odpowiedzi.
Rejestruje publiczny adres HTTPS, na który wysyłamy podpisane (HMAC-SHA256) zdarzenia. Sekret podpisu jest zwracany TYLKO w tej odpowiedzi. Limit: 10 webhooków na konto. Zdarzenia `lead.*` i `email.*` zawierają adresy e-mail i nazwy firm, więc ich subskrypcja wymaga też zakresu `leads:read` (403 `insufficient_scope`).
Zarządzanie webhookami: Dodawanie i usuwanie webhooków; sekret pokazujemy jeden raz przy tworzeniu. Zdarzenia lead.* i email.* zawierają adresy e-mail i nazwy firm, więc ich subskrypcja wymaga też leads:read
Pola ciała żądania
Pole (JSON)
Typ
Opis
url*
string (uri)
Publiczny adres HTTPS (Make, Zapier, n8n, własny serwer).
Błędy tej operacji: validation_error (422), conflict (409), insufficient_scope (403). Wspólne dla wszystkich: 401, 403, 429.
delete/api/v1/webhooks/{id}zakres webhooks:write
Usuń webhook
Usuwa webhook i jego dziennik dostaw. Odpowiedź 204 bez treści.
Zarządzanie webhookami: Dodawanie i usuwanie webhooków; sekret pokazujemy jeden raz przy tworzeniu. Zdarzenia lead.* i email.* zawierają adresy e-mail i nazwy firm, więc ich subskrypcja wymaga też leads:read
Błędy tej operacji: not_found (404). Wspólne dla wszystkich: 401, 403, 429.
Webhooki
Webhooki wysyłają do Twojego systemu podpisany POST z JSON-em, gdy coś się wydarzy. Rejestrujesz je w Ustawieniach albo przez POST /webhooks. Ładunek nie zawiera treści wiadomości, tylko identyfikatory, adres e-mail leada i metadane. Treść odpowiedzi pobierzesz przez GET /replies?include_text=true.
Zdarzenie
Kiedy
lead.created
Nowy lead trafił do Twojej bazy (wyszukiwarka, import, ręcznie, czat/MCP).
lead.status_changed
Status leada zmienił się ręcznie albo automatycznie (odpowiedź, wypisanie, zwrot).
lead.replied
Lead odpowiedział na wiadomość z kampanii (bez zwrotów i autoodpowiedzi).
lead.scored
AI oceniło leada (skala 1-10).
email.opened
Pierwsze otwarcie wiadomości. Apple Mail zawyża otwarcia, traktuj je orientacyjnie.
email.clicked
Pierwsze kliknięcie linku w wiadomości.
email.bounced
Wiadomość nie została dostarczona (zły adres, skrzynka nie istnieje).
email.unsubscribed
Odbiorca wypisał się (link w stopce, nagłówek List-Unsubscribe albo Apple Mail).
campaign.started
Kampania przeszła ze szkicu do wysyłki.
campaign.completed
Kampania skończyła sekwencję dla wszystkich leadów albo została zakończona ręcznie.
rule.triggered
Reguła z akcją „Wyślij webhook” zadziałała dla firmy (np. po odpowiedzi zainteresowanej albo po 3 otwarciach bez odpowiedzi).
X-OutreachPilot-Signature: sha256= i HMAC-SHA256 dokładnej treści żądania, kluczem jest sekret webhooka (pokazywany jeden raz przy tworzeniu).
X-OutreachPilot-Event (typ), X-OutreachPilot-Delivery (id zdarzenia, stałe przy ponowieniu), X-OutreachPilot-Timestamp (sekundy Unix, nie jest objęty podpisem).
Ochrona przed powtórzeniem: sprawdzaj created_at z treści (jest podpisane) i deduplikuj zdarzenia po polu id.
Odpowiedz kodem 2xx w ciągu 10 sekund. Przekierowania (3xx) liczymy jako błąd. Po 10 nieudanych dostawach z rzędu wstrzymujemy wysyłkę na dany adres, dopóki go nie włączysz ponownie.
Node.js
const crypto = require("crypto")
// rawBody = dokładna treść żądania (Buffer albo string, PRZED parsowaniem JSON)
function isValid(rawBody, headers, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex")
const received = headers["x-outreachpilot-signature"] || ""
const signatureOk = expected.length === received.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))
if (!signatureOk) return false
// Podpis obejmuje treść, ale NIE nagłówek Timestamp: wiek sprawdzaj po created_at z treści
// i deduplikuj zdarzenia po polu id (to samo id = to samo zdarzenie).
const { created_at } = JSON.parse(rawBody)
return Math.abs(Date.now() - Date.parse(created_at)) < 5 * 60 * 1000
}
Python
import hashlib, hmac, json, time
from datetime import datetime
def is_valid(raw_body: bytes, headers: dict, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
received = headers.get("x-outreachpilot-signature", "")
if not hmac.compare_digest(expected, received):
return False
# Podpis obejmuje treść, ale NIE nagłówek Timestamp: wiek sprawdzaj po created_at z treści
# i deduplikuj zdarzenia po polu id.
created = datetime.fromisoformat(json.loads(raw_body)["created_at"].replace("Z", "+00:00"))
return abs(time.time() - created.timestamp()) < 300
Make, Zapier i n8n
Nie publikujemy jeszcze własnych aplikacji w Make ani Zapierze. Wszystko, co potrzebne, działa dziś przez dwa elementy: webhooki (OutreachPilot woła Twój scenariusz) i klucz API (Twój scenariusz woła OutreachPilot).
W OutreachPilot dodaj ten adres w Ustawienia → Webhooki, wybierz zdarzenia (np. lead.replied) i kliknij „Wyślij test”. Make rozpozna strukturę danych.
Akcja: moduł HTTP → Make a request woła API:
Make: HTTP → Make a request
URL: https://outreachpilot.pl/api/v1/leads
Method: POST
Headers: Authorization: Bearer op_live_TWÓJ_KLUCZ
Body type: Raw
Content type: JSON (application/json)
Request body: {"company_name": "{{1.firma}}", "email": "{{1.email}}", "tags": ["make"]}
Parse response: Yes
Typowe scenariusze: odpowiedź pozytywna → dodaj deal w CRM i wyślij powiadomienie; nowy wpis z formularza → POST /leads → POST /campaigns/{id}/leads.
Zapier
Wyzwalacz:Webhooks by Zapier → Catch Hook; adres dodaj w Ustawienia → Webhooki i wyślij test.
Akcja:Webhooks by Zapier → Custom Request: metoda POST, URL https://outreachpilot.pl/api/v1/leads, nagłówki Authorization: Bearer op_live_… i Content-Type: application/json, dane jako JSON.
Do pobierania danych użyj Custom Request z metodą GET (np. /replies?sentiment=interested).
Akcja: węzeł HTTP Request z poświadczeniem Header Auth (nazwa Authorization, wartość Bearer op_live_…).
Opcjonalnie sprawdź podpis (zalecane, gdy adres webhooka jest publiczny):
n8n: węzeł Code
// Node "Code" po węźle Webhook (Options → Raw Body: włączone)
const crypto = require("crypto")
const raw = $input.first().binary?.data ? Buffer.from($input.first().binary.data.data, "base64") : Buffer.from(JSON.stringify($input.first().json.body))
const expected = "sha256=" + crypto.createHmac("sha256", $env.OUTREACHPILOT_WEBHOOK_SECRET).update(raw).digest("hex")
if (expected !== $input.first().json.headers["x-outreachpilot-signature"]) throw new Error("Zły podpis")
return $input.all()
Wskazówki: trzymaj klucz w poświadczeniach narzędzia (nie w treści scenariusza), nadaj mu tylko potrzebne zakresy i obsłuż 429 (czekaj Retry-After sekund).
Integracje CRM (push z OutreachPilot)
OutreachPilot wysyła leady do Twojego CRM w jedną stronę. Konfiguracja jest w Ustawienia → API i integracje → Integracje CRM. Dostępne w planach Pro, Business i Agencja. Wysyłka dzieje się w tle (z ponowieniami), więc nie spowalnia aplikacji.
Kiedy wysyłamy
Odpowiedź pozytywna lub pytanie (domyślnie włączone). Odmowy, wypisy i zwroty nie są wysyłane.
Status leada zmieniony na „zainteresowany” (domyślnie włączone).
Ręcznie: przycisk „Wyślij do CRM” na karcie leada i w menu zaznaczenia na liście leadów.
Dla każdego leada pamiętamy identyfikatory obiektów w CRM, więc ponowna wysyłka niczego nie dubluje. Istniejących danych w CRM nie nadpisujemy (uzupełniamy tylko puste pola). Treści maili nie wysyłamy, chyba że włączysz „Dołącz treść odpowiedzi”. Ostatnie 20 zdarzeń widać w dzienniku synchronizacji.
Pipedrive
W Pipedrive: Ustawienia osobiste → API → skopiuj osobisty token.
W OutreachPilot podaj domenę firmy (część przed .pipedrive.com) i token, kliknij „Połącz i sprawdź”.
Opcjonalnie włącz „Twórz deal” i wybierz lejek oraz etap.
OutreachPilot
Pipedrive
Nazwa firmy, NIP
Organizacja (szukamy po polu niestandardowym „NIP”, jeśli je masz, potem po nazwie)
E-mail, imię i nazwisko, telefon
Osoba (szukamy po e-mailu), powiązana z organizacją
Kampania, link do leada
Notatka przy deal/osobie/organizacji
(opcja) deal
Deal w wybranym lejku i etapie, powiązany z osobą i organizacją
HubSpot
W HubSpot: Ustawienia → Integracje → Prywatne aplikacje → utwórz aplikację z zakresami crm.objects.contacts, crm.objects.companies (odczyt i zapis) oraz, dla dealów, crm.objects.deals.
Skopiuj token (pat-…) do OutreachPilot i kliknij „Połącz i sprawdź”.
OutreachPilot
HubSpot
Nazwa firmy, domena strony
Company (szukamy po domenie, potem po nazwie)
E-mail, imię i nazwisko, telefon, stanowisko
Contact (szukamy po e-mailu), powiązany z Company
Kampania, link do leada
Notatka powiązana z kontaktem, firmą i dealem
(opcja) deal
Deal w wybranym lejku i etapie, powiązany z kontaktem i firmą
Livespace
Livespace ma API (klucz i sekret konta, adres https://TWOJA-DOMENA.livespace.io/api/public/json/…; według pomocy Livespace dostępne od pakietu Automation), ale nie utrzymujemy natywnego konektora: pełna specyfikacja pól dealów nie jest publicznie dostępna. Dwie drogi, które działają dziś:
Bez kodu (zalecane): webhook + Make albo Zapier. W karcie „Livespace i inne (webhook)” wklej adres webhooka ze scenariusza. OutreachPilot wyśle zdarzenie crm.lead_push (przykład poniżej), a w Make użyjesz modułów Livespace CRM: Create a Company, Create a Person, Create a Deal (z identyfikatorem procesu sprzedaży) i Create a Note for a Deal. W Zapierze analogicznie: akcje Create Person i Create Deal aplikacji Livespace.
Własny kod: odbierz webhook i wywołaj API Livespace. Uwierzytelnienie: klucz i sekret z Konto → API; po token zgłaszasz się metodą _Api/auth_call/_api_method/getToken, a podpis żądania to sha1(klucz + token + sekret). Pola dealów i notatek sprawdź w dokumentacji API Livespace.
Zdarzenie ma te same nagłówki i podpis HMAC co zwykłe webhooki (sekret pokazujemy raz przy połączeniu). Pole reply.text pojawia się tylko przy włączonej opcji „Dołącz treść odpowiedzi”.
Bezpieczeństwo
Klucz API to hasło do Twojego konta w ramach nadanych zakresów. Nie wklejaj go do kodu przeglądarki ani repozytorium. API celowo nie ma nagłówków CORS.
Przechowujemy wyłącznie skrót SHA-256 klucza i jego prefiks. Utraconego klucza nie odzyskamy: odwołaj go i utwórz nowy.
Nadawaj najmniejsze możliwe zakresy i osobny klucz każdemu narzędziu. Ustaw datę wygaśnięcia tam, gdzie to możliwe.
Tworzenie i odwołanie klucza trafia do dziennika zdarzeń widocznego w Ustawieniach. Przy każdym żądaniu zapisujemy czas ostatniego użycia klucza.
Tokeny CRM szyfrujemy (AES-256-GCM) i nigdy nie pokazujemy ich po zapisaniu. Rozłączenie CRM kasuje token i stan synchronizacji.