companies: "*" to include all managed companies and future connections.
Each event identifies its company, so one receiver can route updates to the
right client.
Use the shared webhook guide for testing,
signature verification, duplicate handling, retries, and delivery
troubleshooting. Follow
Consume Partner webhooks
for a complete API example.
Subscription ownership
Manage subscriptions with your Partner key through POST/partner/v2/webhooks/.
Subscriptions belong to the Partner; creating a Partner-managed company does
not create a company webhook.
A Partner key with X-On-Behalf-Of-Company may read a managed company’s
/v2/webhooks/ and /v2/webhook-deliveries/, but every write there — create,
update, delete, rotate-secret, test, redeliver — answers 403 with code
use_partner_webhooks, before any If-Match or query-parameter check.
Partners subscribe to Case events through /partner/v2/webhooks/ with a
companies selector, as described below.
Partner subscription commands follow the shared rules: rotate-secret and
redeliver take no request body (400 unexpected_body); a PATCH that
repeats the stored values is a 200 no-op and leaves updated_at and the
ETag unchanged; and POST /partner/v2/webhook-deliveries/{id}/redeliver/
accepts settled deliveries only — a pending, retrying, or delivering
delivery answers 409 delivery_in_progress.
Partner subscriptions expose writable max_consecutive_failures (a JSON
integer from 1 to 1000, default 50). It sets how many consecutive terminal
delivery failures switch the subscription off. An automatically disabled
subscription reads back with enabled: false and auto_disabled: true; fix
the destination and set enabled: true to reset the failure counter.
A test event on a disabled subscription answers 409 conflict
(Webhook is disabled; enable it before sending a test event.). A test event
whose type is not in the subscription answers 400
(Webhook is not subscribed to event type: <type>.).
Receive Case and Mahnservice events
A Partner-owned subscription may include Case event types and Mahnservice event types from the company catalog. It then needs acompanies selector saying whose events it receives: the literal "*" for
every managed company, or a non-empty list of company UUIDs. A Partner
subscription whose events contain a Case event but no companies is
rejected with 400 and code required_for_case_events on companies; a
UUID the Partner has no available Case access to answers 400
company_not_accessible; anything else answers 400 invalid. Lifecycle-only
subscriptions leave companies as null. The wildcard events: ["*"]
without companies stays lifecycle-only and never widens into Case events.
Access is re-checked at delivery time, not only when the event is queued: a
company that declines, is released, or is otherwise no longer available stops
producing deliveries to the Partner’s subscriptions, and resumes when access
is restored. A delivery that was already queued for such a company is closed
as failed with error_message: partner_access_unavailable — no HTTP call
is made and the attempt does not count against the endpoint’s health. The
check runs right before each send without holding up the disconnect, so an
attempt already past it can still arrive just after access ends. Every later
attempt, retry, and manual redelivery is suppressed. Only
company.access.revoked itself still goes out, as the final event of that
connection. Such a delivery is no longer visible to you, so redelivering it
answers 404. A Case event delivered to a Partner subscription is
byte-identical to the delivery the company’s own subscription receives, same
id included, so a receiver fed by both deduplicates naturally.
The Partner event feed
includes only events available to your integration. Use it to reconcile
company, Case, and Mahnservice changes.
Partner lifecycle events
The Partner OpenAPI schema publishesPartnerWebhookEvent for deliveries and
PartnerEventFeedEvent for the event feed. Both dispatch on type, with the
company event families above and these Partner lifecycle families:
When events are sent
company.created is emitted once after the company and inline users commit,
before the company.user.added event of each inline user. Readiness emits only
when its boolean changes and never reveals private issue details. Confirmation
emits once per authorization version without user PII. Revocation is the last
event authorized by the previous state; restoration resumes future events
without replaying missed ones.
company.user.added also emits when a cancelled pending membership is
re-added or a revoked membership is reactivated. company.user.revoked emits
after an active membership is soft-revoked and contains the company and
membership UUIDs, never the user’s email, name, or the operator-supplied
reason. company.user.activated emits when a pending membership becomes
active — the person accepted the invite, by signing in or by setting a
password. Completing password setup activates only the membership of the
company whose invitation it was, so company.user.activated fires for that
company only. company.user.invite_expired emits from a daily sweep for every
pending membership whose setup invite has lapsed unaccepted; the membership
stays pending_setup and a resend issues a fresh invite. Both carry the
company and membership UUIDs only. Resend, role correction, and pending
cancellation do not emit user lifecycle events. A release by the Partner
emits company.access.revoked with reason: "partner_released" in data;
a client-side decline keeps its existing shape.
Diagnose missing company events
Check that the subscription includes the event type and, for a company event, an appropriatecompanies selector. events: ["*"] without companies
receives Partner lifecycle events only. Check the company’s current access:
disconnection stops its deliveries, and restoration resumes future events
without replaying the gap. Fetch current data or use the
Partner event feed
to reconcile what is available.
Inspect delivery history
for failed attempts and use the
shared troubleshooting table
for receiver and signature problems.