Hello! This is the backend API for
echolotl.lol. You can use
these endpoints however you like, but please don't abuse them.
There are rate limits.
This is a mega WIP as I learn Elysia and backend stuff. You can view
the source code
here.
Gets echolotl's current playing song on Spotify.
15 requests over 1 minute
Returns the currently playing song on Spotify, if any.
Gets echolotl's latest status.
15 requests over 2 minutes
Returns the latest status object.
Gets recent statuses, newest first.
limit (optional number): Number of statuses to
return. Defaults to 10.
cursor (optional number): The ID of the last status from the previous page, used for pagination.
15 requests over 2 minutes
Returns a list of statuses and the count returned.
POST /status
lock
Creates a new status entry.
Requires an
Authorization: Bearer <PASSKEY> header, where
PASSKEY matches the server's configured
PASSKEY environment variable.
{
"text": "string (1-100 chars)",
"emoji": "emoji (optional, nullable)"
}
15 requests over 2 minutes
Authorization bearer
token.Lets you login with Discord for echolotl.lol. This is what will power any authenticated requests.
Redirects the browser to Discord's OAuth consent screen. Sets
a short-lived oauth_state cookie for validation.
20 requests over 1 minute, shared across all Discord auth routes
GET
/auth/discord/authenticate
This is the redirect_uri configured on the
Discord application and it's not meant to be called
directly. Discord redirects here with a code and
state after the user approves the login.
This does more additional checks to ensure the Discord account is at least a month old (to mitigate spam),
and then saves the Discord user info to the database and sets a session cookie for future authenticated requests.
code (string): Authorization code provided by
Discord.
state (string): Must match the
oauth_state cookie set in /auth/discord/.
20 requests over 1 minute, shared across all Discord auth routes
session cookie set.
Destroys the session tied to the session cookie
(if any) and clears the cookie.
20 requests over 1 minute, shared across all Discord auth routes
Returns a confirmation text string.
Reads the session cookie and returns the
associated user as a full user object. This always returns the full user object, even if the user has enabled anonymous mode.
20 requests over 1 minute, shared across all Discord auth routes
Anonymous mode disabled:
Anonymous mode enabled:
PATCH
/auth/discord/me
lock
Requires an active session cookie. Can be used to set the anonymous mode for the current user,
and returns a full user object with the updates. This is a non-anonymous object for the same reason as the GET /auth/discord/me endpoint.
20 requests over 1 minute, shared across all Discord auth routes
Returns the updated user.
DELETE
/auth/discord/me
lock
Requires an active session cookie. This will delete the current user and all their data from the database.
20 requests over 1 minute, shared across all Discord auth routes
Returns a confirmation text string.
GET
/auth/discord/user/:userId
Returns a user object for the given userId.
If the user has enabled anonymous mode, this will return a redacted user object with a generic username and display name, and no avatar hash.
userId (string): The user's userId, as returned by
/auth/discord/me or itself.
20 requests over 1 minute, shared across all Discord auth routes
Anonymous mode disabled:
Anonymous mode enabled:
userId.
Lets people leave comments (and replies) on art pieces (or, theoretically, anything in the future), identified by a
slug. Posting, editing, and deleting comments requires an
active session cookie from
Discord OAuth. The slugs provided aren't checked for existence in actuality.
GET
/comments/user/:userId
Returns the user's public profile along with their most recent comments, newest first. Comments don't include author info here since it's the same user for all of them.
userId (string): The user's standalone
userId.
limit (optional number): Number of comments to
return. Defaults to 10.
100 requests over 1 minute, shared across all comment routes
Returns the user and their comments.
userId.GET
/comments/s/:slug
Returns the top-level (non-reply) comments for the given
slug, oldest first. Each comment includes a
replyCount so you can fetch
replies separately from
GET /comments/:id/replies.
slug (string): The slug of the art piece
being commented on.
limit (optional number): Number of top-level
comments to return. Defaults to 10, capped at
50.
cursor (optional number): The id of
the last comment from the previous page. Pass the response's
nextCursor to fetch the next page.
100 requests over 1 minute, shared across all comment routes
Returns the slug, a page of top-level comments, and a
nextCursor (or null if there are
no more pages).
POST
/comments/s/:slug
lock
Requires an active session cookie. Creates a new
top-level comment on the given slug.
slug (string): The identifier for the art piece
being commented on.
Plain text body (Content-Type: text/plain),
1-5000 characters.
100 requests over 1 minute, shared across all comment routes
Returns the newly created comment.
GET
/comments/:id
Returns a single comment by id, along with its
replyCount. Fetch replies separately from
GET /comments/:id/replies.
id (number): The comment's numeric ID.
100 requests over 1 minute, shared across all comment routes
Returns the comment.
id isn't an integer.id exists.GET
/comments/:id/replies
Returns the direct replies to the comment id,
oldest first. Each reply includes its own
replyCount; fetch nested replies by calling this
route again with the reply's own id.
id (number): The parent comment's ID.
limit (optional number): Number of replies to
return. Defaults to 10, capped at 50.
cursor (optional number): The id of
the last reply from the previous page. Pass the response's
nextCursor to fetch the next page.
100 requests over 1 minute, shared across all comment routes
Returns the parent comment's id, a page of
replies, and a nextCursor (or
null if there are no more pages).
id isn't a valid integer.id exists.POST
/comments/:id
lock
Requires an active session cookie. Creates a
reply to the comment id, inheriting its slug.
id (number): The parent comment's numeric ID.
Plain text body (Content-Type: text/plain),
1-5000 characters.
100 requests over 1 minute, shared across all comment routes
Returns the newly created reply.
id isn't an integer.id exists.PATCH
/comments/:id
lock
Requires an active session cookie. You can only
edit your own comments, and only if they haven't been
deleted.
id (number): The comment's numeric ID.
Plain text body (Content-Type: text/plain),
1-5000 characters.
100 requests over 1 minute, shared across all comment routes
Returns the updated comment.
id isn't a valid integer.id exists.DELETE
/comments/:id
lock
Requires an active session cookie. You can only
delete your own comments. The comment's body is replaced
with [deleted] rather than being removed
entirely, so replies stay intact.
id (number): The comment's numeric ID.
100 requests over 1 minute, shared across all comment routes
id isn't a valid integer.id exists.