developers

The API.

Everything the dashboard does, it does through these endpoints. They are session-authenticated, so you can drive them from a signed-in browser or a script that carries your cookies.

Authentication

Requests are authenticated with the d_session cookie. Any request that changes something must also send an x-csrf-token header whose value is the d_csrf cookie, and must come from an allowed origin. Both are set when you sign in.

Rate limits

Writes are limited to 120 requests a minute per account, uploads to 40 per five minutes, and sign-in attempts to 8 per ten minutes per address. Exceeding one returns 429 with the number of seconds until the window resets.

Errors

Errors are JSON: { "ok": false, "error": "message" }. Validation failures also include an issues array naming the offending field.

Endpoints

GET/api/username/check?name=Is a name free?
POST/api/auth/registerusername, email, password
POST/api/auth/loginidentifier, password, totp?
POST/api/auth/logoutEnds the current session
GET/api/profileYour profile, plan and limits
PATCH/api/profilePartial update; premium fields are capped server-side
GET/api/linksAll of your links
PUT/api/linksReplace the whole list; array order sets position
GET/api/widgetsAll of your widgets
PUT/api/widgetsReplace the whole list
GET/api/tracksYour audio playlist
PUT/api/tracksReplace the playlist
POST/api/uploadmultipart/form-data with a file field
GET/api/mediaYour uploads and storage usage
DELETE/api/mediaid
GET/api/account/sessionsSigned-in devices
DELETE/api/account/sessionsid, or all: true
GET/api/account/exportEverything we store about you, as JSON
POST/api/billing/checkoutStarts a Stripe Checkout session
GET/api/widget?type=&id=Cached third-party widget data

Example

curl -X PATCH https://dreaded.lol/api/profile \
  -H 'content-type: application/json' \
  -H "x-csrf-token: $D_CSRF" \
  -b "d_session=$D_SESSION; d_csrf=$D_CSRF" \
  -d '{"bio":"new bio","appearance":{"accent":"#ff4a1c"}}'

Anything your plan does not include is silently reset to a free-tier value rather than rejected, so a script cannot smuggle premium settings in.