Re-register the tenant's existing webhook subscription at a provider
Re-registers this tenant’s EXISTING webhook subscription at the provider, without rotating the connection.
WHAT IT DOES, EXACTLY: it reads the connection this tenant currently serves deliveries on, recomposes that connection’s delivery URL, and sends the provider a subscription write carrying the declared resource set pointed at that URL. The connection record is untouched — same connection token, same signing key, same delivery URL — so a URL or a key you are already holding stays valid, and nothing you have configured elsewhere needs to change.
⚠️ WHAT IT DOES NOT DO, AND THE LIMIT IS THE POINT. When the provider reports a subscription as BLOCKED after repeated delivery failures, the procedure that returns it to service is NOT MEASURED by this service. This operation re-registers; whether the provider’s consecutive-error counter resets, and whether deliveries resume, is something you OBSERVE afterwards — in the provider’s own subscription state and in this service’s webhook.subscription.blocked gauge — rather than something this call promises. Confirm the procedure with the provider before treating a blocked channel as repaired.
⛔ THE WRITE REPLACES THE PROVIDER’S RESOURCE ARRAY WHOLE, WHICH IS WHY IT READS BEFORE IT WRITES. The resources field of the answer is the entire set that is registered afterwards; any resource the provider held that is not in that list would no longer be subscribed, and the provider reports nothing about a removal. On a deployment where several consumers share one provider credential, that array is shared too, so the resource at risk may not even be yours. This operation therefore reads the subscription the provider currently holds under your credential BEFORE writing, and refuses with 409 if that subscription carries anything outside the set below — the answer then names resources that would have been removed, and nothing is written. The read exists only to refuse: the write’s resource array is always the declared set and is never assembled from what the provider reports. If that read cannot be completed the call is refused with 502, because a read that failed says nothing about what the provider is holding.
⚠️ THERE IS ONE WAY PAST THAT 409, AND IT IS EXPLICIT: send the optional acknowledge_revoking naming exactly the resources the refusal reported. The call then proceeds and THOSE RESOURCES ARE REMOVED from the provider’s subscription. The set is measured again on that call and compared against what you sent, so a name you left out — or a name the provider is not holding outside the declared set — is refused with another 409 saying which, and still writes nothing. It is NOT a conditional write: the provider offers none, so the window between this service reading the subscription and writing it is as open as it ever was. What the acknowledgement rules out is acting on a stale picture — a resource that appeared between the refusal you read and the call you sent makes your call FAIL instead of destroying something you never saw.
IT IS A LIVE TENANT’S SELF-SERVICE ACTION, AND THAT BOUNDS WHO YOU ACT AS, NOT WHAT YOU AFFECT. The tenant comes from the credentials you authenticate with and there is no tenant parameter anywhere in this request, so you cannot name somebody else. The provider, however, files ONE subscription per provider credential, not one per tenant: where several tenants share a credential, that single subscription is what this write re-points at YOUR tenant’s delivery URL, and the others keep receiving deliveries only because their own health poller notices the registered address is not the one it composed and re-registers on its next tick. Which tenants share a credential is not something this service can see.
THE ANSWER CARRIES THE DELIVERY URL, WHICH IS A CREDENTIAL — the connection’s routing token is a segment of it. Treat the response body as secret. It carries NO signing key.
A tenant with no connection to re-present, and a provider_type this deployment does not serve, are both refused with 404. The operation declares no Idempotency-Key: a retry re-executes, and re-executing sends the identical write.
⚠️ A RETRY OF A CALL THAT CARRIED acknowledge_revoking IS THE ONE EXCEPTION TO THAT, AND THE 409 IT ANSWERS PROVES LESS THAN IT LOOKS LIKE. Once a forced write has landed, the resources you acknowledged are gone from the provider’s subscription — so on the retry they are no longer outside the declared set, your acknowledgement names something that is not there, and the call is refused with 409. That refusal reports one thing only: the set measured on this call is no longer the set you named. It is consistent with your first call having landed, and equally consistent with it never having reached the provider while some OTHER actor removed those resources in the meantime — on a shared provider credential, another consumer’s own health poller is exactly such an actor. So it is not evidence of either on its own: do not read it as proof the write happened, and do not read it as “nothing was written” either. Check whether the removal already happened before re-sending, and re-send WITHOUT the field to see the current state. This is why a retry on a timeout should be a plain call, not a repeated force.
Autorizações
JWT bearer token issued by the identity provider.
Cabeçalhos
Tenant organization ID. Accepted but ignored: the tenant is determined by the credentials you authenticate with, so sending this header, or sending a different value in it, changes nothing.
Parâmetros de caminho
Provider whose subscription is being re-registered, for example BTG. Matched case-insensitively; a provider this deployment does not serve is refused with 404.
"BTG"
Corpo
OPTIONAL, and it forces a write that would otherwise be refused. Name EXACTLY the resources the 409 reported, each one spelled as the refusal printed it — a bare entity name, or an entity/EVENT pair where only an event under a declared entity is at risk — and the re-registration proceeds and REMOVES them from the provider's subscription. The set is re-measured at the provider on this call and compared against what you sent: a name you left out, or a name the provider is not holding outside the declared set, is refused with another 409 that says which. Comparison is exact per name — no case folding, no trimming — and insensitive to order; repeats are collapsed. Omit the field, or send an empty list, to get the ordinary refusal. It is NOT a conditional write: the provider offers none, so it cannot close the window between this service's read and its write. What it closes is the window between the refusal you read and the call you sent.

