Přejít na obsah
Dokumentace

Průvodce

Vytvoření OAuth aplikace

Umožněte uživatelům připojit vaši aplikaci k jejich workspace v Emailitu přes OAuth 2.1 a PKCE, včetně registrace klienta, obnovy tokenů, odvolání a chyb.

Aktualizováno 1. 10. 2026

Emailit provozuje autorizační server OAuth 2.1 na https://api.emailit.com. Použijte ho, když vytváříte integraci, například CRM, no-code nástroj nebo AI klienta, která jedná jménem uživatelů Emailitu. Uživatelé se přihlásí a schválí přístup v prohlížeči a vy dostanete tokeny pro workspace, které vyberou, aniž byste kdy pracovali s jejich API klíči. Stejný postup používá MCP server.

Jak to funguje

  1. Zaregistrujte klienta dynamickou registrací klienta, nebo hostujte dokument s metadaty klienta.

  2. Pošlete uživatele na autorizační URL s výzvou PKCE (code challenge).

  3. Uživatel se přihlásí do Emailitu, vybere workspace, které může vaše aplikace používat, a schválí požadovaný rozsah oprávnění.

  4. Emailit přesměruje zpět na vaše URI pro přesměrování s jednorázovým autorizačním kódem.

  5. Vyměňte kód za přístupový token platný 15 minut a obnovovací token.

  6. Volejte API s přístupovým tokenem a po vypršení ho obnovte.

Endpointy

Metoda Cesta Účel
GET /.well-known/oauth-authorization-server Metadata autorizačního serveru (RFC 8414)
GET /.well-known/oauth-protected-resource Metadata chráněného zdroje pro REST API
GET /.well-known/oauth-protected-resource/mcp Metadata chráněného zdroje pro MCP server
POST /oauth/register Dynamická registrace klienta (RFC 7591)
GET /oauth/authorize Přihlášení a souhlas v prohlížeči
POST /oauth/token Výměna kódu nebo obnovovacího tokenu
POST /oauth/revoke Odvolání uděleného přístupu jeho obnovovacím tokenem (RFC 7009)
GET /oauth/grants Výpis udělených přístupů (přihlášeného uživatele, nebo s API klíčem jednoho workspace)
POST /oauth/grants/:id/revoke Odvolání uděleného přístupu
PUT /oauth/grants/:id/workspaces Změna workspace, které smí udělený přístup používat (uživatel, který aplikaci připojil)

Všechny cesty jsou na https://api.emailit.com.

Zjistěte metadata serveru

Terminal
curl https://api.emailit.com/.well-known/oauth-authorization-server
JSON
{
  "issuer": "https://api.emailit.com",
  "authorization_endpoint": "https://api.emailit.com/oauth/authorize",
  "token_endpoint": "https://api.emailit.com/oauth/token",
  "registration_endpoint": "https://api.emailit.com/oauth/register",
  "revocation_endpoint": "https://api.emailit.com/oauth/revoke",
  "jwks_uri": "https://api.emailit.com/.well-known/jwks.json",
  "code_challenge_methods_supported": ["S256"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "response_types_supported": ["code"],
  "token_endpoint_auth_methods_supported": ["none", "client_secret_basic", "client_secret_post"],
  "client_id_metadata_document_supported": true,
  "authorization_response_iss_parameter_supported": true,
  "scopes_supported": ["sending", "full"]
}

MCP klienti místo toho začínají u metadat chráněného zdroje. Neautentizovaný požadavek na https://api.emailit.com/mcp vrací 401 s WWW-Authenticate: Bearer resource_metadata="https://api.emailit.com/.well-known/oauth-protected-resource/mcp" a tento dokument odkazuje na autorizační server:

JSON
{
  "resource": "https://api.emailit.com/mcp",
  "authorization_servers": ["https://api.emailit.com"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["sending", "full"]
}

Rozsahy oprávnění

Oprávnění Co uděluje
sending Odesílání a přeposílání e-mailů a přeplánování, rušení a opakované odeslání. Stejný přístup jako klíč jen pro odesílání.
full Všechny endpointy REST API a nástroje MCP. Stejný přístup jako klíč s plným přístupem.

full už zahrnuje vše, co povoluje sending. Pokud vaše aplikace jen odesílá, žádejte o sending, jinak o full; přijímá se i sending full oddělené mezerou. Pokud scope vynecháte, Emailit použije všechna oprávnění, která klient zaregistroval.

Zaregistrujte klienta

Klienta můžete zaregistrovat dvěma způsoby. Oba fungují se všemi postupy na této stránce.

Dynamická registrace klienta

Pošlete požadavek na registraci. Autentizace není potřeba a z každé IP adresy lze zaregistrovat až 20 klientů za hodinu.

Terminal
curl https://api.emailit.com/oauth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "Acme CRM",
    "redirect_uris": ["https://crm.acme.com/oauth/emailit/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"],
    "scope": "full",
    "token_endpoint_auth_method": "client_secret_basic",
    "client_uri": "https://crm.acme.com",
    "logo_uri": "https://crm.acme.com/logo.png"
  }'
Pole Povinné Popis
client_name Ano Zobrazuje se na stránce se souhlasem. Nejvýše 200 znaků.
redirect_uris Ano 1 až 10 URI pro přesměrování. Viz Pravidla pro URI pro přesměrování.
grant_types Ne Musí obsahovat authorization_code; může obsahovat refresh_token. Výchozí hodnota jsou obě.
response_types Ne Jen code.
scope Ne Oprávnění oddělená mezerou. Výchozí hodnota je sending full.
token_endpoint_auth_method Ne none (výchozí) pro veřejné klienty, jako jsou desktopové, mobilní a prohlížečové aplikace; client_secret_basic, nebo client_secret_post pro aplikace na straně serveru.
client_uri Ne Domovská stránka vaší aplikace.
logo_uri Ne Logo zobrazené na stránce se souhlasem.

Odpověď 201 zopakuje metadata a přidá client_id. Důvěrní klienti dostanou také client_secret, který se zobrazí jen jednou:

JSON
{
  "client_id": "3e8a1f52-7c4b-4d29-8e6f-1a5b9c0d2e73",
  "client_id_issued_at": 1790847000,
  "client_name": "Acme CRM",
  "redirect_uris": ["https://crm.acme.com/oauth/emailit/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "scope": "full",
  "token_endpoint_auth_method": "client_secret_basic",
  "client_uri": "https://crm.acme.com",
  "logo_uri": "https://crm.acme.com/logo.png",
  "client_secret": "Ky7WI2z5HxoT6q1z19tuiIev_U1zX0_FKhIIfh0OBco",
  "client_secret_expires_at": 0
}

client_secret_expires_at je vždy 0: tajné klíče klientů nevyprší. Každý klient, veřejný i důvěrný, musí používat PKCE.

Dokument s metadaty klienta

Pokud vaše aplikace může hostovat statický soubor JSON, registraci můžete vynechat. Publikujte dokument na HTTPS URL a tuto URL použijte jako client_id:

https://crm.acme.com/oauth/client.json
{
  "client_id": "https://crm.acme.com/oauth/client.json",
  "client_name": "Acme CRM",
  "client_uri": "https://crm.acme.com",
  "logo_uri": "https://crm.acme.com/logo.png",
  "redirect_uris": ["https://crm.acme.com/oauth/emailit/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "token_endpoint_auth_method": "none",
  "scope": "full"
}
  • client_id v dokumentu se musí přesně shodovat s URL dokumentu.
  • token_endpoint_auth_method musí být none. Jde o veřejné klienty, kteří se spoléhají na PKCE.
  • URI pro přesměrování s HTTPS musí mít stejný název hostitele jako dokument.
  • Emailit dokument stáhne během autorizace s časovým limitem 5 sekund a bez následování přesměrování a na 5 minut si ho uloží do mezipaměti.
  • Stránka se souhlasem místo client_name zobrazuje název hostitele dokumentu, například crm.acme.com.

Tuto metodu používají AI klienti: ChatGPT, Claude a Grok se identifikují vlastními dokumenty s metadaty klienta, takže se připojí bez předchozí registrace. U Groku Emailit přijímá také přesměrování na console.x.ai.

Pravidla pro URI pro přesměrování

  • URI https:// jsou povolená.
  • http:// je povolené jen pro loopback: 127.0.0.1, localhost a [::1]. U loopback URI se port při autorizaci může lišit, ale hostitel, cesta a dotaz se musí shodovat. localhost a 127.0.0.1 jsou různí hostitelé.
  • Pro nativní aplikace jsou povolená vlastní schémata, například cursor://, vscode:// nebo com.acme.crm://.
  • URI se schématy file, ftp, data, javascript, blob, about a vbscript a jakékoli URI s #fragment se odmítnou.
  • Kromě portů u loopbacku se redirect_uri, které pošlete, musí přesně shodovat s některým zaregistrovaným.

Pošlete uživatele do Emailitu

Pro každou autorizaci vygenerujte ověřovací kód (code verifier) a výzvu PKCE a náhodnou hodnotu state:

JavaScript
import { createHash, randomBytes } from 'node:crypto';

const codeVerifier = randomBytes(32).toString('base64url');
const codeChallenge = createHash('sha256').update(codeVerifier).digest('base64url');
const state = randomBytes(16).toString('base64url');
// Store codeVerifier and state in the user's session.

Pak přesměrujte prohlížeč uživatele na autorizační endpoint:

Text
https://api.emailit.com/oauth/authorize
  ?response_type=code
  &client_id=3e8a1f52-7c4b-4d29-8e6f-1a5b9c0d2e73
  &redirect_uri=https%3A%2F%2Fcrm.acme.com%2Foauth%2Femailit%2Fcallback
  &scope=full
  &state=Jq3k9V0n2xR7bLm1
  &code_challenge=zsrvXVr2pbLDHbccAx_NY9osQ6nwqTnDZlIeFWKQOsg
  &code_challenge_method=S256
  &resource=https%3A%2F%2Fapi.emailit.com
Parametr Povinné Popis
response_type Ano code
client_id Ano ID vašeho klienta, nebo URL vašeho dokumentu s metadaty.
redirect_uri Ano Jedno z vašich zaregistrovaných URI pro přesměrování.
code_challenge Ano SHA-256 ověřovacího kódu zakódovaný v Base64url.
code_challenge_method Doporučené S256. plain není podporované.
scope Doporučené sending, nebo full. Musí jít o oprávnění, které klient zaregistroval.
state Doporučené Náhodná hodnota, kterou zkontrolujete při zpětném volání.
resource Ne Zdroj, který chcete volat (RFC 8707): https://api.emailit.com pro REST API, nebo https://api.emailit.com/mcp pro MCP. Tokeny v každém případě fungují na obou.

Tuto URL otevřete v prohlížeči uživatele. Nestahujte ji ze svého backendu.

Co uživatel uvidí

  1. Přihlášení do Emailitu. Uživatel zadá e-mail a heslo. Pokud pro dvoufázové ověření používá ověřovací aplikaci, zadá potom kód z ní nebo záložní kód.
  2. Výběr workspace. Stránka zobrazí vaše logo, název klienta (nebo název hostitele vašeho dokumentu s metadaty) a oprávnění, o která žádáte. Uživatel vybere All my workspaces, což zahrnuje i workspace, které vytvoří nebo ke kterým se připojí později, nebo Only these workspaces se zaškrtnutými workspace, a zvolí, ve kterém vaše aplikace začne.
  3. Povolení přístupu. Uživatel vybere Allow access, nebo Deny.

Jeden udělený přístup může zahrnovat více workspace. Uživatel může seznam později změnit ve webovém rozhraní v sekci Account > Connected apps a vaše aplikace změnu uvidí při dalším požadavku.

Po schválení Emailit přesměruje na vaše URI pro přesměrování:

Text
https://crm.acme.com/oauth/emailit/callback?code=XvRKyG5Pkplrd3xkRNaEayKkpkebEMdF&state=Jq3k9V0n2xR7bLm1&iss=https%3A%2F%2Fapi.emailit.com

Zkontrolujte, že state odpovídá uložené hodnotě a že iss je https://api.emailit.com. Kód platí 10 minut a lze ho použít jen jednou. Pokud uživatel vybere Deny, obsahuje přesměrování místo kódu error=access_denied.

Vyměňte kód za tokeny

Pošlete POST na tokenový endpoint jako application/x-www-form-urlencoded (přijímá se i JSON). Pošlete stejné redirect_uri a původní ověřovací kód:

Terminal
curl https://api.emailit.com/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  -d redirect_uri=https://crm.acme.com/oauth/emailit/callback \
  -d code_verifier="$CODE_VERIFIER"

S client_secret_basic pošlete ID klienta a tajný klíč v hlavičce Authorization: Basic. S client_secret_post místo toho pošlete client_id a client_secret jako pole formuláře. Tajný klíč neposílejte oběma způsoby.

JSON
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im9hdXRoLWhzMjU2In0…",
  "token_type": "Bearer",
  "expires_in": 900,
  "refresh_token": "XvRKyG5Pkplrd3xkRNaEayKkpkebEMdFn0h1VIuqixAOXybMtJfK8w",
  "scope": "full"
}

Přístupový token platí 15 minut (expires_in je v sekundách). Zacházejte s ním jako s neprůhledným řetězcem: neparsujte ho a nespoléhejte na jeho obsah.

Volejte API

Přístupový token používejte jako bearer token pro REST API i MCP server, přesně jako API klíč:

Terminal
curl https://api.emailit.com/v2/domains \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Požadavky na REST API běží ve výchozím workspace uděleného přístupu: v tom, ve kterém se uživatel rozhodl začít, nebo na který ho později změnil. Nástroje MCP mohou argumentem workspace cílit i na jiný povolený workspace. Každý požadavek používá udělené oprávnění a roli uživatele ve workspace, takže požadavek mimo rozsah oprávnění nebo volání cesty vyhrazené roli Admin uživatelem s rolí Member vrací 403. Pokud uživatel workspace opustí, přijde o něj i udělený přístup.

Obnova tokenů

Než přístupový token vyprší, nebo když požadavek vrátí 401, získejte nový:

Terminal
curl https://api.emailit.com/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=refresh_token \
  -d refresh_token="$REFRESH_TOKEN"
  • Výměna. Každá obnova vrací nový refresh_token platný 60 dní. Uložte ho a starý zahoďte. Dokud obnovujete do 60 dní, připojení nevyprší.
  • Detekce opakovaného použití. Pokud se starý obnovovací token použije znovu déle než minutu poté, co byl nahrazen, Emailit vrátí invalid_grant (Refresh token reuse detected) a odvolá celý udělený přístup. Uživatel pak musí aplikaci autorizovat znovu. Obnovy provádějte postupně, aby dva workery nikdy nepoužily stejný obnovovací token.
  • Užší oprávnění. Parametrem scope můžete získat přístupový token s užším rozsahem oprávnění, než má udělený přístup. O širší požádat nemůžete.

Odvolejte udělený přístup

Když uživatel Emailit od vaší aplikace odpojí, odvolejte udělený přístup jeho obnovovacím tokenem:

Terminal
curl https://api.emailit.com/oauth/revoke \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d token="$REFRESH_TOKEN"

Endpoint autentizuje vašeho klienta stejně jako tokenový endpoint a vždy vrací 200 s prázdným tělem. Odvolání obnovovacího tokenu odvolá celý udělený přístup: jeho přístupové tokeny přestanou fungovat při dalším požadavku. Přístupové tokeny nelze odvolat samostatně; token_type_hint=access_token vrací invalid_request.

Uživatelé mohou přístup vaší aplikace odvolat i ze své strany na stránce Připojené aplikace ve webovém rozhraní, nebo přes API udělených přístupů popsané níže.

Spravujte udělené přístupy

API udělených přístupů vypisuje a mění udělené přístupy ze strany uživatele. Přijímá relaci uživatele ve webovém rozhraní, nebo API klíč s plným přístupem:

Volající GET /oauth/grants POST /oauth/grants/:id/revoke PUT /oauth/grants/:id/workspaces
Uživatel, který aplikaci připojil Jeho udělené přístupy napříč všemi workspace Odvolá celý udělený přístup Změní workspace uděleného přístupu
API klíč s plným přístupem Udělené přístupy, které zahrnují workspace klíče Odebere workspace klíče z uděleného přístupu; když žádný workspace nezbude, udělený přístup se odvolá Není povoleno (403)

Každý udělený přístup v seznamu má tento tvar:

JSON
{
  "id": "9b1f6c2e-4d3a-4f8e-9a7b-2c5d8e1f0a3b",
  "client_id": "https://chatgpt.com/oauth/client.json",
  "client": { "name": "ChatGPT", "uri": "https://chatgpt.com", "logo_uri": null },
  "default_workspace": { "id": "w3f9a1c2e", "name": "Acme" },
  "workspace_access": "selected",
  "workspaces": [{ "id": "w3f9a1c2e", "name": "Acme" }],
  "scopes": ["sending", "full"],
  "resource": "https://api.emailit.com/mcp",
  "created_at": "2026-10-01T09:30:12Z",
  "revoked_at": null,
  "revoked_reason": null
}

Pokud chcete změnit workspace uděleného přístupu, pošlete access (all, nebo selected), u selected také workspace_ids a volitelně default_workspace_id, které musí patřit mezi povolené workspace:

Terminal
curl -X PUT https://api.emailit.com/oauth/grants/9b1f6c2e-4d3a-4f8e-9a7b-2c5d8e1f0a3b/workspaces \
  -H "Authorization: Bearer $DASHBOARD_SESSION" \
  -H "Content-Type: application/json" \
  -d '{ "access": "selected", "workspace_ids": ["w3f9a1c2e"], "default_workspace_id": "w3f9a1c2e" }'

Uživatel musí být členem každého workspace, který vybere. Odvolaný udělený přístup nelze upravit (409); aplikace se musí připojit znovu.

Chyby

Endpointy OAuth vracejí chyby ve formátu OAuth, ne ve formátu chyb REST API:

JSON
{
  "error": "invalid_grant",
  "error_description": "Authorization code has expired"
}
Chyba Stav Kdy
invalid_request 400 Parametr chybí nebo je neplatný, klient není při autorizaci známý, redirect_uri není zaregistrované, code_challenge_method není S256, nebo byl tajný klíč klienta poslán v hlavičce i v těle.
invalid_client 401 Tokenový endpoint nebo endpoint pro odvolání nedokáže klienta autentizovat: neznámý klient, chybějící nebo špatný tajný klíč.
invalid_grant 400 Kód je neplatný, použitý nebo vypršel; redirect_uri nebo ověřovací kód PKCE nesouhlasí; nebo je obnovovací token neplatný, vypršel, byl odvolán nebo použit opakovaně.
invalid_scope 400 Oprávnění není podporované, klient ho nezaregistroval, nebo při obnově přesahuje udělený přístup.
unsupported_response_type 400 response_type není code.
unsupported_grant_type 400 grant_type není authorization_code ani refresh_token.
access_denied Přesměrování Uživatel vybral Deny.
too_many_requests 429 Více než 20 registrací za hodinu z jedné IP adresy.
server_error 500 Na straně Emailitu se něco pokazilo. Zkuste to znovu.

Dokud nejsou client_id a redirect_uri ověřené, zobrazují se chyby autorizace v prohlížeči jako JSON a nikdy se nepřesměrovávají. Potom se chyby přesměrují na vaše zpětné volání (s error, error_description, state a iss) jen u loopback URI, URI s vlastním schématem a u klientů s dokumentem s metadaty; ostatní klienti dostanou chybovou stránku v JSON. Odmítnutí uživatelem přes Deny se přesměruje vždy.

Kontrolní seznam zabezpečení

  • client_secret a obnovovací tokeny uchovávejte na serveru a ukládejte je šifrované. Nikdy nedávejte tajný klíč klienta do mobilní, desktopové ani prohlížečové aplikace; místo toho použijte veřejného klienta s PKCE.
  • Pro každou autorizaci vygenerujte nový state a ověřovací kód a při zpětném volání zkontrolujte state a iss.
  • Registrujte přesná URI pro přesměrování. Jako zpětná volání nepoužívejte otevřené přesměrovače.
  • Každý udělený přístup ukládejte s workspace, ke kterému patří, a na invalid_grant reagujte tak, že uživatele požádáte o nové připojení.
  • Pokud jen odesíláte e-maily, žádejte o sending.
Udělené přístupy, platnost tokenů a odvolání.
Endpointy, které mohou vaše tokeny volat.
Pro vlastní skripty jsou klíče jednodušší.
Postup OAuth v praxi.

Byla tato stránka užitečná?

Děkujeme za zpětnou vazbu.

Děkujeme, čteme každou zprávu.