Event-Driven Orbs
Webhooks
An Amp plugin can create a public HTTP endpoint that stores events and wakes its orb. Use a webhook when an external service such as GitHub needs to start work in an orb. Unlike a portal, a webhook does not expose a server running inside the orb.
Webhooks work only in plugins running in Amp-managed orbs. Register the handler from the plugin’s entry point with a short, stable key:
const { url } = await amp.createWebhook({
key: 'github-events',
headers: ['x-hub-signature-256'],
handler: async (event, ctx) => {
await verifyAndApply(event.id, event.body, event.headers['x-hub-signature-256'], ctx.signal)
},
}) The returned url accepts POST requests. Configure that URL in the external service. Ask Amp to
create and load the plugin when you do not need to write it yourself. Run amp plugins show-docs inside the orb to read the Plugin API installed there.
Example
You can ask Amp in an orb thread to write, load, and wire up the webhook plugin for you:
Amp writes the plugin into .amp/plugins/, loads it, and replies with the webhook URL to paste
into the external service.
Delivery Guarantees
The registration belongs to the orb thread, plugin, and key. Registering the same key again keeps the same URL across plugin reloads and orb restarts. An incoming request is stored before Amp returns HTTP 202, then Amp wakes a paused orb and calls the handler. HTTP 202 means that Amp queued the event. It does not mean that the handler finished.
Delivery is at least once. Store event.id with the action that the handler performs so a retry
cannot apply the same action twice. The handler has 30 seconds to finish. Pass ctx.signal to
cancellable network calls and throw when a temporary failure should be retried. Keep longer work
in a durable queue or start another thread.
Rate Limits
Each endpoint accepts a burst of 10 new events and refills at 10 events per minute. Amp returns
HTTP 429 when the endpoint exceeds that rate or has 100 events waiting. Rate limit responses
include Retry-After. A request body can be at most 1 MB. Send a stable Idempotency-Key header
when the sender retries a request. A retry for an event that is still waiting does not use more
rate capacity.
Security
Treat the webhook URL as a password. Anyone with it can submit events without signing in to Amp. Do not commit it, put it in a thread message, or write it to normal logs. If you save it in the orb, use a gitignored file that only the owner can read. Archiving the owning thread pauses the orb and makes the URL return HTTP 404.
Amp does not verify signatures from the external service. Add each signature or authorization
header to headers, store the matching secret in project settings,
and verify the signature before acting. Amp discards request headers that the plugin did not list.
Validate the body and requested headers as untrusted input, and never use webhook text as agent
instructions without checking it first.
Trigger Settings
Use trigger settings to pause or delete a webhook. Pausing keeps its URL but rejects new events until you resume it. Deleting it revokes the URL and removes its queued events.
Testing
You can test an endpoint without putting its URL in shell history:
read -rsp 'Webhook URL: ' AMP_WEBHOOK_URL && echo
curl --fail-with-body \
-X POST \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: test-event-1' \
--data '{"action":"test"}' \
"$AMP_WEBHOOK_URL"
unset AMP_WEBHOOK_URL For scheduled and recurring work, see Automations.