Grosso
⌘K

Docs · Events

Webhooks

Every change your agent needs to know about is an event. Grosso POSTs it to your endpoint, signed, and retries for about three days until you answer 2xx.

01 — Register

Register an endpoint

Endpoints are per mode. A test endpoint only ever receives test events.

POST /v1/webhook_endpointscURL
curl https://pay.grosso.ai/v1/webhook_endpoints \
  -H "Authorization: Bearer $GROSSO_API_KEY" \
  -H "idempotency-key: hook_prod_1" \
  -d '{ "url": "https://agent.example.com/grosso",
        "enabled_events": ["payment_request.paid",
                           "refund.succeeded"] }'

02 — Verify

Verify signatures

The grosso-signature header carries a timestamp and an HMAC-SHA256 of <t>.<raw body> keyed with your endpoint secret.

grosso-signatureHEADER
grosso-signature: t=1793125652,v1=5f2b9c0e7d1a…

Verify against the raw body

Parse JSON after verifying. Re-serialising the body changes the bytes and breaks the signature.

03 — Retries

Retries

A non-2xx answer or a 10-second timeout schedules the next attempt. After the last one, the delivery is marked failed; replay it with POST /v1/webhook_endpoints/:id/replay.

  1. Attempt 1 after 0
  2. Attempt 2 after 1m
  3. Attempt 3 after 5m
  4. Attempt 4 after 30m
  5. Attempt 5 after 1h
  6. Attempt 6 after 3h
  7. Attempt 7 after 6h
  8. Attempt 8 after 12h
  9. Attempt 9 after 12h
  10. Attempt 10 after 12h
  11. Attempt 11 after 12h
  12. Attempt 12 after 12h

12 attempts across about three days.

04 — Event types

Event types

EventWhen
payment_request.createdA request was created and is open.
payment_request.paidThe payer paid. Tell the human it’s done.
payment_request.paid_after_closePaid after it expired or was canceled. The money stays with the payee; decide whether to refund.
payment_request.refundedFully or partially refunded.
refund.pending_approvalAn agent asked; waiting on the owner.
refund.approved · refund.rejectedThe owner said yes, or no. An approved refund goes to Stripe next.
refund.succeeded · refund.failedStripe’s final answer.
dispute.updated · dispute.closedA payer disputed a charge, or the dispute was decided.
payee.invited · payee.updatedA payee was invited, or its metadata changed.
payee.pausedThe payee can’t take payments; its open requests were canceled.
payee.unpausedThe pause was lifted; the payee’s status is back.
account.suspendedYour account was suspended; payees are paused and open requests canceled.
account.identity_verification.updatedYour identity check moved forward.