Skip to content

API - Getting Started

The EasyDonate API lets you read your account data and control your timer widget programmatically. It is a closed alpha gated behind the OPENAPI_ALPHA whitelist - ask the team to be added before you start.

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)

Quick start with an API key

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

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

List recent donations:

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

Control the timer (needs write:timer):

bash
curl -X POST https://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://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://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://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://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 30 days. 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.