GET /v1/events — the event log

Everything that happens to your programme, as a retrievable list — poll it to reconcile your ledger, catch a delivery your endpoint missed, and learn when a waitlisted user gets a seat. When push webhooks ship, they will deliver these same events; building on this log now means changing nothing later.

GET /v1/events?product_id=<your app id>&limit=25
Authorization: Bearer {your_api_key}

Reply: { "events": [ { "id", "type", "createdAt", "data" } ], "hasMore": true } — newest first. Page with starting_after=<the last event's id>. Every data carries productUserId; the rest is per type:

typeWhendata
user.enrolledA user was enrolled (first call only)seatState
seat.openedA waitlisted user was promoted to an earning seat
binding.createdAn X account was connected — a first qualifying post, or a member approving a waiting accountplatform, handle
binding.pendingAn account posted the code and is waiting for approval on the rewards pageplatform, handle
binding.removedAn X account was disconnected — by the user on the rewards page, or by you as the ownerplatforms
post.verifiedA post passed verification and was creditedamount, rewardType, postedAt, postUrl
reward.deliveredYour endpoint accepted a deliveryrewardReference, amount, rewardType
reward.revokedA credited post was deleted or its disclosure edited out before the day-5 settlement. Also pushed to your reward endpoint as kind: "revocation", so this row is audit rather than the way you find outrewardReference, amount, reason (post_deleted | disclosure_removed), postUrl
reward.delivery_failedA delivery exhausted its retries (seven over ~3 days) without a 2xxrewardReference, amount, attempts

Reconciliation recipe: nightly, walk events since your last stored cursor; every reward.delivered should exist in your rewards table by rewardReference. A reward.delivery_failed is a reward your endpoint never accepted — but it is not stranded: once your endpoint answers any delivery with 2xx again, failed rewards are requeued automatically and arrive on their own. Crediting from the event is still sanctioned belt-and-braces (idempotent by reference; a later redelivery dedupes into a 2xx), and X-Earnesty-Pending on each successful delivery tells you the backlog size — but with automatic recovery, this log is an audit tool, not a correctness requirement.

product_id is the App ID — the same value the guide’s constants table calls App ID; the query parameter keeps the older name.

Errors are { "error", "code" }: missing_field, invalid_limit, invalid_cursor (400), unauthorized (401), app_not_found (404).


Working with a coding agent? Point it at earnesty.app/docs/integration/llms-full.txt — every page on this site as one Markdown file, no key required.