Events
Read back every event Moon generated, delivered or not.
Every event Moon generates for your organization is stored and readable, whether or not its webhook delivery succeeded. If your endpoint was unreachable, this is how you catch up.
The recovery path
A delivery that fails is retried for about 46 hours (see Webhooks). If your endpoint was down longer than that, or you want to confirm nothing was missed, read the events back:
cURL
curl --request GET \
--url 'https://api.themooncard.com/v2/api-gateway/events?start_date=2026-08-16&status=failed' \
--header 'accept: application/json' \
--header 'x-api-key: YOUR_API_KEY'Each event carries the same type and data the webhook POST would have carried, so you can hand data to the same handler that consumes live deliveries and get the same result. The event's id is the webhook_ in the delivered body, which is what lets you tell a replay apart from something you already processed.
What an event looks like
JSON
{
"events": [
{
"id": "9f8b7a6c-5d4e-4f3a-8b2c-1d0e9f8a7b6c",
"type": "CARD_TRANSACTION",
"created_at": "2026-08-17T12:00:00.000Z",
"delivery": {
"status": "delivered",
"attempts": 1,
"max_attempts": 9,
"last_attempt_at": "2026-08-17T12:00:01.000Z",
"next_attempt_at": null,
"delivered_at": "2026-08-17T12:00:01.000Z",
"response_status_code": 200
},
"data": { }
}
],
"pagination": { }
}The delivery object answers two different questions:
- Did it arrive?
statusisdelivered,failed, orpending, andresponse_is what your endpoint answered on the attempt being described —status_ code nullwhen no reply arrived at all, which is a different situation from a500and worth distinguishing when you open a support request. - Is anything still coming?
next_alone tells you: a timestamp means another attempt is due then,attempt_ at nullmeans the event is settled and nothing further will be sent. You do not need to know the retry schedule to read it.
attempts counts the attempts actually made, and max_ is the ceiling for this delivery.
Filters
| Parameter | Values |
|---|---|
status | pending, delivered, failed |
start_, end_ | A calendar day (2026-08-16) or a full instant with an explicit offset (2026-08-16T09:15:00Z) |
current_, per_ | Standard pagination; up to 100 per page |
Filtering by a type outside that list returns an empty page rather than an error. The list grows as new event types are added, so read it as the set that exists today rather than a fixed enum — see Webhooks for what each one means.
To fetch one event you already have the id for, use GET /events/{event_. An id that does not exist, or that belongs to another organization, returns a 404.
Working out what you missed
The practical shape of a catch-up, after an outage on your side:
- List with
status=failedand astart_covering the outage.date - Page through with
per_, ordering bypage=100 created_as returned.at - Feed each
datato your normal handler, keyed on the eventidso a replay of something you did process is a no-op. - Re-run the same query afterwards — anything still
pendinghas attempts left and will arrive on its own.
Events remain readable after the endpoint that produced them is deleted or replaced, so changing your webhook URL does not cost you the history.
Related
- Webhooks — signature verification, the retry schedule and the delivery contract.
- Pagination — page parameters and the
paginationobject. - Data formats and ids — timestamp and identifier formats.
Last updated October 22, 2026