Settings — Hooks & Webhooks
This page is the bidirectional automation surface: inbound webhooks push events into Sublarr (e.g. “Sonarr just imported episode X — start searching”), and outbound hooks push events out (e.g. “Sublarr just downloaded a subtitle — tell my custom CMS”).
Inbound webhooks
Section titled “Inbound webhooks”The webhook receiver lives at /api/v1/webhooks/<source>. Each enabled source has its own URL and HMAC secret:
| Source | URL path | When the source fires |
|---|---|---|
| Sonarr | /api/v1/webhooks/sonarr | New episode imported, episode upgraded, series deleted. |
| Radarr | /api/v1/webhooks/radarr | New movie imported, movie upgraded, movie deleted. |
| Custom JSON | /api/v1/webhooks/custom | Any system you control. Schema documented below. |
| Field | Effect |
|---|---|
| Enabled | Source toggle. |
| URL | Read-only; copy into the source system’s connection settings. |
| Secret | Required HMAC secret. The source signs payloads with it; Sublarr verifies. |
| Auto-translate on import | Queue a translation job as soon as the inbound webhook fires. |
| Test | Sends a sample payload through the receiver path so you see if it would have worked. |
Sonarr / Radarr setup
Section titled “Sonarr / Radarr setup”In the *arr UI:
- Settings → Connect → + → Webhook.
- Name:
Sublarr. - On Grab / On Import / On Upgrade — select per your needs.
- URL: paste from this page.
- Method:
POST. - Headers: add
X-Webhook-Secret: <secret-from-this-page>. - Test → Sublarr should respond
OK. - Save.
Custom JSON
Section titled “Custom JSON”Send any system’s events to /api/v1/webhooks/custom with the body:
{ "event": "media_imported", "series_title": "...", "season": 1, "episode": 1, "file_path": "/media/...", "metadata": { "any": "additional fields" }}Required fields: event, file_path. Other fields are optional and used when present.
Outbound hooks
Section titled “Outbound hooks”When something interesting happens inside Sublarr, an outbound hook fires HTTP POST to a configured URL. Useful for integrating with custom dashboards, in-house metadata systems, or just centralised logging.
| Field | Effect |
|---|---|
| Label | Display name. |
| URL | Where Sublarr POSTs. |
| Method | POST (default) or PUT. |
| Headers | Custom headers (e.g. Authorization: Bearer ...). |
| Events | Which event types fire this hook. |
| Retry | On failure: none / 3x exponential / 10x linear. |
| Timeout (s) | Request timeout. |
| Test | Sends a sample payload immediately. |
Outbound payload shape
Section titled “Outbound payload shape”{ "event": "subtitle_downloaded", "timestamp": "2026-05-05T18:42:11.123Z", "subsystem": "search", "data": { "series_title": "Frieren", "season": 1, "episode": 7, "language": "de", "provider": "jimaku", "score": 7.2, "file_path": "/media/anime/Frieren/Season 01/E07.de.srt" }, "instance_id": "<sublarr-uuid>"}The data block varies per event type — full schema lives in Settings → System → Diagnostics → Hook payloads.
Available outbound events
Section titled “Available outbound events”| Event | Fires when |
|---|---|
subtitle_downloaded | A subtitle is written to disk. |
subtitle_upgraded | An existing subtitle was replaced by a higher-scoring one. |
translation_completed | A translation job finishes. |
translation_failed | A translation job ends in failure. |
search_failed | All providers exhausted with no match. |
extract_completed | An embedded subtitle was extracted from a container. |
cleanup_finished | A cleanup pass completed. |
scheduler_job_failed | A scheduled job failed three times in a row. |
library_scan_finished | A library scan completed. |
Authentication
Section titled “Authentication”Sublarr uses two patterns for outbound auth:
| Pattern | Setup |
|---|---|
| Bearer token | Add Authorization: Bearer <token> to the hook’s Headers field. |
| HMAC signing | When the receiver expects a signature, paste the shared secret into Hook secret; Sublarr signs the body with X-Sublarr-Signature: sha256=<hex>. |
Hook history
Section titled “Hook history”Every outbound hook firing writes to history:
| Column | Effect |
|---|---|
| Timestamp | When fired. |
| Hook | Which hook. |
| Event | The event type. |
| Status | 200 / 4xx / 5xx / timeout. |
| Latency | Round-trip time. |
| Body excerpt | First 1 KB of the request body. |
| Response excerpt | First 1 KB of the response body. |
Use the history table when debugging “why didn’t my downstream get the event?” — the response body usually contains the upstream’s rejection reason.
Concurrency and retries
Section titled “Concurrency and retries”| Setting | Default | Effect |
|---|---|---|
| Max concurrent hook firings | 4 | Per-Sublarr-instance cap. |
| Default retry policy | 3x exponential | Override per-hook. |
| Retry backoff base (s) | 5 | First retry waits this; doubles each subsequent. |
If all retries fail, the hook firing is dropped and a hook_failed log line is written. A failed firing does not block the originating event from being processed.