Skip to content

API - Getting Started

The EasyDonate API lets you read your account data and control your timer widget programmatically. OAuth applications, the Connect with EasyDonate flow, and personal API keys are open to every account - create yours from Dashboard -> Developer.

The full reference (auto-generated OpenAPI 3) is rendered with Redoc at /docs.

Authentication

Every request uses the same header:

Authorization: Bearer <token>

There are two kinds of token:

TokenTypeActs asWhere you get it
Bearer ezdn_v1_<cuid>Personal API keyYour own accountDashboard -> Developer -> API Keys
Bearer <jwt>OAuth access tokenThe consenting userOAuth flow (below)

API keys are opaque strings prefixed with ezdn_v1_. OAuth access tokens are short-lived signed JWTs, so they look like xxxxx.yyyyy.zzzzz rather than a prefixed string.

Tokens are scoped - a request is rejected with 403 if the token lacks the scope the endpoint requires.

Scopes

ScopeGrants
read:profileAccount identity (PII redacted)
read:donationsDonation transactions, stats, charts, trends, export
read:widgetsWidget configs + data + timer/connection status
write:timerControl the running timer (play/pause/reset/adjust)
read:subscriptionYour EasyDonate plan, limits, sponsorships
read:creatorPublic creator lookups + your own creator stats
read:channelsDonation channel status/type (secrets stripped)
write:donationsCreate external donations (inbound events)

See Inbound Donations for pushing donate events from another platform.

Quick start with an API key

Create a key in the dashboard, pick the scopes you need, then:

bash
curl https://api.easydonate.app/api/v1/me \
  -H "Authorization: Bearer ezdn_v1_xxxxxxxxxxxxxxxx"

List recent donations:

bash
curl "https://api.easydonate.app/api/v1/donations?page=1" \
  -H "Authorization: Bearer ezdn_v1_xxxxxxxxxxxxxxxx"

Control the timer (needs write:timer):

bash
curl -X POST https://api.easydonate.app/api/v1/widgets/timer/control \
  -H "Authorization: Bearer ezdn_v1_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"action":"adjust","ms":60000}'

Every response uses the standard envelope:

json
{ "statusCode": 200, "data": {} }

OAuth2 (act on behalf of other users)

For apps that act on behalf of EasyDonate users, register an application (Dashboard -> Developer -> Applications) to receive a client_id and client_secret. The flow is Authorization Code + PKCE (PKCE is mandatory).

  1. Send the user to the authorize screen:
https://easydonate.app/oauth/authorize?client_id=<client_id>
  &redirect_uri=<your_callback>
  &scope=read:profile read:donations
  &state=<random>
  &code_challenge=<S256_challenge>
  &code_challenge_method=S256
  1. The user logs in and approves. EasyDonate redirects to redirect_uri?code=<code>&state=<state>.

  2. Exchange the code for tokens from your backend:

bash
curl -X POST https://api.easydonate.app/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "<code>",
    "client_id": "<client_id>",
    "client_secret": "<client_secret>",
    "redirect_uri": "<your_callback>",
    "code_verifier": "<verifier>"
  }'

Response:

json
{
  "access_token": "<jwt>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "ezdn_v1_rt_...",
  "scope": "read:profile read:donations"
}

The access_token is a signed JWT - pass it verbatim in the Authorization header. The refresh_token is an opaque string prefixed with ezdn_v1_rt_.

  1. Call the API with the access token:
bash
curl https://api.easydonate.app/api/v1/me \
  -H "Authorization: Bearer <jwt>"
  1. Refresh when it expires (the refresh token rotates - store the new one):
bash
curl -X POST https://api.easydonate.app/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "refresh_token": "ezdn_v1_rt_...",
    "client_id": "<client_id>",
    "client_secret": "<client_secret>"
  }'
  1. Revoke a token (or remove the connection):
bash
curl -X POST https://api.easydonate.app/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{"token":"ezdn_v1_rt_...","client_id":"<client_id>","client_secret":"<client_secret>"}'

Access tokens live 1 hour; refresh tokens never expire by default (per-app custom TTL configurable from the dashboard). Access tokens are stateless JWTs and cannot be revoked individually - revoke the refresh token (or remove the connection) to cut off an app. Unverified apps may connect at most 20 users

  • request verification in the dashboard to lift the cap.

Rate limits

Requests are limited to 60 per minute per credential. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; exceeding the limit returns 429.