proposal_accepted event into an API call, you hand the proposal to an adapter and it performs the write, returning a result you can log. Two adapters ship with ShoulderTap.
The adapter interface
Every adapter implements a single method:proposal_accepted event arrives.
OpenMetadata adapter
Writes an acceptedglossary.definition proposal into an OpenMetadata glossary term — it PATCHes the term’s description with the definition plus a provenance footer, so the catalog records who answered and when.
Base URL of your OpenMetadata instance.
Bearer token for the OpenMetadata API.
A function mapping a proposal to the fully-qualified name of the glossary term to update. Because a
ContextProposal doesn’t carry the original request’s context, you supply this mapping — typically keyed by proposal.request_id.Source: Dana Kim via ShoulderTap, 2026-07-20. The adapter rejects non-glossary kinds (detail contains unsupported kind) and a resolver that returns None (detail is no entity FQN). If structuring failed and structured is null, it falls back to the raw answer.
Webhook adapter
The universal escape hatch: POSTs the accepted proposal as JSON to any URL. Use it to forward answers into a system that doesn’t have a dedicated adapter yet.result.success is False and result.detail describes the failure — the adapter never raises, so a failed write-back won’t crash your consumer.
Putting it together
Theexamples/openmetadata_sync/webhook_consumer.py in the repository wires the OpenMetadata adapter behind a FastAPI webhook: it registers as a glossary.definition consumer, remembers which entity each request maps to, and on each proposal_accepted event PATCHes the definition into OpenMetadata. It’s a complete, runnable template for a write-back consumer.