Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/shadownrx/apisquare/llms.txt

Use this file to discover all available pages before exploring further.

Authenticate as an admin by posting credentials to /api/admin/login. On success, the server sets an admin_session HTTP-only cookie valid for 7 days. Pass this cookie on all subsequent admin API calls. The endpoint uses Vercel KV to persist the session token across serverless function instances, with an in-memory fallback for local development.

Request

curl -X POST https://your-app.vercel.app/api/admin/login \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{"username": "admin", "password": "yourpassword"}'

Request body

username
string
required
Admin username. Compared against the ADMIN_USERNAME environment variable; defaults to admin if the variable is not set.
password
string
required
Plaintext password. Compared against ADMIN_PASSWORD using bcrypt.compare when the stored value begins with $2b$ or $2a$; otherwise a direct string comparison is performed.

Success response

HTTP 200
{ "success": true }
A Set-Cookie header is included with the following attributes:
AttributeValue
Nameadmin_session
HttpOnlytrue
SameSiteStrict
Max-Age604800 (7 days)
Securetrue in production only
Path/
The session token is a 64-character lowercase hex string generated with crypto.randomBytes(32).toString('hex'). It is stored in Vercel KV under the key session:{token} with a 7-day TTL, and also registered in the in-memory globalSessions Set for local development.
success
boolean
Always true on a successful login.

Error responses

HTTP 400 — Invalid JSON

Returned when the request body cannot be parsed as JSON.
{ "error": "Solicitud inválida" }
error
string
Human-readable error message.

HTTP 400 — Missing credentials

Returned when either username or password is absent from the request body.
{ "error": "Credenciales requeridas" }
error
string
Human-readable error message.

HTTP 401 — Wrong credentials

Returned when the username or password does not match.
{
  "error": "Credenciales incorrectas",
  "remaining": 3,
  "blocked": false
}
error
string
Human-readable error message.
remaining
integer
Number of failed-login attempts remaining before the IP is locked out. When this reaches 0, blocked is set to true and the next request returns HTTP 429.
blocked
boolean
true when remaining === 0, indicating the IP address is now locked out for 15 minutes.

HTTP 429 — Brute-force lockout

Returned when the IP address has exceeded the maximum number of failed attempts.
{
  "error": "Demasiados intentos fallidos. Intentá nuevamente en 15 minuto(s).",
  "blocked": true,
  "resetIn": 900
}
The number in the error message is dynamic — it reflects the actual minutes remaining until the lockout expires (e.g. "Intentá nuevamente en 1 minuto(s)." or "Intentá nuevamente en 15 minuto(s).").
error
string
Human-readable error message in Spanish, including the remaining wait time in minutes.
blocked
boolean
Always true on HTTP 429.
resetIn
integer
Seconds remaining until the lockout expires and the IP may attempt to log in again.

Brute-force protection

The endpoint tracks failed login attempts per IP address using Vercel KV, with a Map-based in-memory store as a local development fallback.
ParameterValue
Max attempts5 per IP
Lockout period15 minutes (900 seconds)
KV key patternratelimit:login:{ip} with 15-min TTL
Reset triggerCounter is cleared on successful login
The IP address is resolved from the X-Forwarded-For header (first entry), then the X-Real-IP header. It falls back to 127.0.0.1 when neither header is present.

Build docs developers (and LLMs) love