Skip to main content

Webhooks

Webhooks tell your systems the moment something changes in a project, so you don't have to poll the API on a timer. TextSetu sends a signed HTTP request to a URL you choose, every time an event you've subscribed to happens.

Typical uses:

  • Rebuild or redeploy when translations are approved.
  • Invalidate a cache or CDN when a value changes.
  • Kick off a CI job when a branch is merged.
  • Sync to another system when keys are added or removed.

Over the API. Webhooks can be managed entirely over the API as well as in the UI, and the payload schemas, headers and signature algorithm are all documented per-endpoint. See the Webhooks endpoints in the API Reference.


Creating a webhook

  1. Open Project settings → Webhooks and choose New webhook.
  2. Enter the Endpoint URL. It must be publicly reachable over HTTPS.
  3. Pick the events you want. Start from a preset — All events, Translation content, Pipeline events — then fine-tune, or tick individual events.
  4. Leave Include AI-generated changes off unless you want them (see Keeping the volume sane).
  5. Save. TextSetu shows a signing secret beginning whsec_.

:::warning Copy the signing secret immediately It is shown once and cannot be retrieved afterwards. If you lose it, rotate the secret to get a new one. :::

Your receiver uses that secret to verify each request genuinely came from TextSetu. Until you verify signatures, treat the endpoint as untrusted — anyone who learns the URL could post to it.

Confirming it works

Use Test on the endpoint row. That queues a ping event, which shows up in the delivery log within seconds. It's the quickest way to prove the URL is reachable and your signature check is correct before you depend on real events.


Events

EventFires when
Key createdA translation key is added
Key updatedA key's name, description, tags or screenshot changes
Key deletedA key is removed
Translation updatedA translation's text or approval status changes, for one language
Branch createdA translation branch is created
Branch mergedA branch is merged into the main line, with a summary of what changed
Import completedA file import finishes successfully
Export completedA file export finishes and is ready to download
Language added / removedA project language changes

Subscription is explicit. An endpoint only ever receives the events you tick. There is no "everything" option that silently grows — if TextSetu adds a new event type later, existing endpoints keep receiving exactly what they received before until you opt in. New events can't become surprise traffic.

Branches

Changes made on a branch are not delivered. Branch edits are staged as a diff and are deliberately not part of project activity, so editing a translation or adding a key on a branch fires nothing.

You're notified at the boundaries instead:

  • Branch created when the work starts.
  • Branch merged when it lands — carrying the number of keys added, keys deleted and values updated.

For a branch-based workflow, treat Branch merged as your signal to re-pull. That is the point at which the branch's changes become live on main.

Keeping the volume sane

Three things stop webhooks becoming a firehose:

  • An import fires one event, not one per key. A 5,000-key import is a single Import completed delivery.
  • AI-generated changes are excluded by default. A bulk AI translation run can produce thousands of Translation updated events, so the Include AI-generated changes switch is off until you turn it on.
  • Unsubscribed events are never queued at all — not sent, not retried, and absent from the log.

The delivery log

Every attempt is recorded beneath the endpoints table for 30 days, whether it succeeded or not. Click a row to see the exact payload sent, the response received, and how many attempts have been made.

StatusMeaning
pendingQueued, not attempted yet
successDelivered — your endpoint returned a 2xx
failedFailed, and a retry is scheduled
deadGave up — attempts exhausted, or the response was permanently unacceptable
skippedNever sent (endpoint disabled, or the source change no longer exists)

Filter by endpoint, event type or status, and sort any column. Use Refresh to pull in deliveries that have landed since you opened the page — retries arrive minutes or hours later, and the log doesn't update on its own.

Replaying a delivery

Replay re-sends a delivery's original payload — useful after fixing an outage on your side. The replay is a new delivery with its own webhook ID, so a receiver that de-duplicates on that ID will still process it. The original record is left untouched.


Retries

A failed delivery is retried up to five times over roughly seven and a half hours:

5s → 5min → 30min → 2h → 5h

What gets retried:

  • Retried: 408, 429, any 5xx, plus timeouts and connection or TLS failures.
  • Not retried: other 4xx responses (401, 403, 404, 410, …). Those won't fix themselves, and retrying for seven hours wouldn't help — the delivery log tells you exactly what to fix.
  • Not retried: redirects. TextSetu never follows them, so a 3xx means the configured URL is wrong.

If your endpoint returns a Retry-After header on a 429 or 503, TextSetu honours it.

Auto-disabling

After 10 consecutive failed deliveries an endpoint is switched off automatically and shown as Auto-disabled. That represents roughly ten exhausted retry windows, so it means genuinely dead rather than a brief blip.

Fix your side, then Enable it again — which also clears the failure count, giving the endpoint a full retry budget.


Rotating the signing secret

Choose Rotate secret to issue a new one. The previous secret keeps working for 24 hours, and during that window TextSetu signs each request with both. A receiver that accepts any valid signature can roll over without dropping a single delivery.

Deploy the new secret within those 24 hours. After that, only the new one is sent.


URL requirements

URLs are checked when you save and again on every delivery — DNS can change after an endpoint is created.

  • HTTPS is required.
  • No credentials in the URL (https://user:pass@…) and no #fragment.
  • Must resolve to a public address. Private, loopback, link-local (including cloud metadata addresses) and carrier-NAT ranges are rejected, so a webhook can't be used to reach internal infrastructure.
  • Redirects are never followed — point the endpoint at its final URL.

Delivery guarantees

Design your receiver around these three properties:

  • At-least-once. A delivery can arrive more than once. De-duplicate on the webhook-id header.
  • Unordered. Two changes made in quick succession may arrive in either order. Don't infer sequence from arrival time.
  • Acknowledge fast. Return a 2xx quickly and do the real work asynchronously — TextSetu gives up on an attempt after 10 seconds.

Privacy

Translation updated includes the old and new translation text, sent to the URL you configure. That's the point of the event, but it does mean translation content leaves TextSetu — subscribe deliberately, and only to endpoints you control.


Troubleshooting

SymptomCause
Every delivery is dead with a 401/403Your endpoint is rejecting the request — usually signature verification. Check you're using the base64-decoded secret bytes, not the whsec_… string.
Deliveries are dead with a 404Wrong path, or the route only accepts GET. Webhooks are always POST.
The signature never matchesVerify against the raw request body, before JSON parsing. Re-serializing changes the bytes.
The endpoint shows Auto-disabled10 consecutive failures. Fix the receiver, then Enable.
Nothing arrives at allCheck the event is ticked and the endpoint is Enabled — and if the change was made on a branch, see Branches.
Nothing arrives from AI translationTurn on Include AI-generated changes.
A delivery is skippedThe endpoint was disabled when it came up for sending, or the key it described was deleted before it went out.

Permissions

Creating, editing and deleting webhooks — and viewing delivery payloads — requires project management access, the same level as project API tokens, since a webhook secret can be used to impersonate TextSetu to your receiver. Listing endpoints and the delivery log needs project read access. See Roles and permissions.