API documentation

Back to dashboard

devplatform API

A PHP/MySQL API gateway with developer accounts, API key management, rate limiting, and request logging. All endpoints return JSON.

Base URL
https://plutusalerts.com/devplatform

Authentication

There are two separate credential types, don't mix them up:

Developer session token (JWT)

Issued by /login.php. Used for account-level endpoints: managing API keys and viewing dashboard stats. Expires after 1 hour.

Authorization: Bearer <jwt>
API key

Issued by /keys.php. Used only for actual API calls through the gateway. Doesn't expire, but can be revoked.

Authorization: Bearer ak_xxxxxxxx

Rate limits

Each API key has its own limit (default 60 requests/min, configurable per key). Limits are enforced on a fixed one-minute window. Every gateway response includes these headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42

Exceeding the limit returns:

429 Too Many Requests
{ "error": "Rate limit exceeded, try again next minute" }

Errors

All errors return a JSON body with an error field and an appropriate status code:

StatusMeaning
401Missing, invalid, or expired token/key
404Unknown endpoint path
409Email already registered
422Missing or invalid request fields
429Rate limit exceeded

POST /register.php

Create a developer account. No auth required.

Request body
{
  "name": "Jay Williams",
  "email": "you@example.com",
  "password": "at least 8 characters"
}
curl
curl -X POST https://plutusalerts.com/devplatform/register.php \
  -H "Content-Type: application/json" \
  -d '{"name":"Jay","email":"you@example.com","password":"secretpass"}'
Response 201
{ "token": "eyJhbGciOi...", "developer_id": 2 }
POST /login.php

Exchange credentials for a developer session token.

Request body
{ "email": "you@example.com", "password": "secretpass" }
curl
curl -X POST https://plutusalerts.com/devplatform/login.php \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"secretpass"}'
Response 200
{ "token": "eyJhbGciOi..." }
GET /keys.php

List your API keys. Requires developer session token. Raw keys are never returned, only the prefix.

curl
curl https://plutusalerts.com/devplatform/keys.php \
  -H "Authorization: Bearer $TOKEN"
Response 200
[
  {
    "id": 1,
    "key_prefix": "ak_9f3b2c",
    "name": "Production",
    "status": "active",
    "rate_limit_per_min": 120,
    "created_at": "2026-08-14 10:02:00",
    "revoked_at": null
  }
]
POST /keys.php

Create a new API key. Requires developer session token. The raw key is only ever shown in this response, store it now.

Request body
{ "name": "Production", "rate_limit_per_min": 60 }
curl
curl -X POST https://plutusalerts.com/devplatform/keys.php \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Production","rate_limit_per_min":60}'
Response 200
{ "id": 3, "api_key": "ak_088851060870e245...", "name": "Production" }
DELETE /keys.php?id={id}

Revoke an API key. Requires developer session token. Revoked keys immediately stop working against the gateway.

curl
curl -X DELETE "https://plutusalerts.com/devplatform/keys.php?id=3" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{ "revoked": true }
GET /gateway.php?path={endpoint}

The actual API gateway. Requires an API key (not a developer token). Routes to one of the sample backend endpoints below.

PathMethodDescription
/v1/weatherGETMock weather for a city (?city=)
/v1/quoteGETRandom inspirational quote
/v1/echoPOSTEchoes back the submitted JSON body
curl
curl "https://plutusalerts.com/devplatform/gateway.php?path=/v1/weather&city=Chesapeake" \
  -H "Authorization: Bearer ak_xxxxxxxx"
Response 200
{ "city": "Chesapeake", "temp_f": 72, "conditions": "Clear" }
GET /dashboard_stats.php?range={range}

Aggregated usage metrics across all of your API keys. Requires developer session token. range is one of 24h, 7d, 30d (default 24h).

curl
curl "https://plutusalerts.com/devplatform/dashboard_stats.php?range=24h" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "requests_over_time": [{ "bucket": "2026-09-06 14:00:00", "count": 11 }],
  "status_breakdown": [{ "bucket": "success", "count": 11 }],
  "response_time_percentiles": { "p50": 3, "p95": 4, "p99": 4 },
  "usage_by_endpoint": [
    { "path": "/v1/quote", "method": "GET", "count": 10 },
    { "path": "/v1/weather", "method": "GET", "count": 1 }
  ]
}