API / Documentation
A public, read-only JSON API for ArtLair. Requires a free personal API key.
{"ok":true,"data":...}
and errors like {"ok":false,"error":{...}}.
The API is read-only (GET requests only).
Authentication
Every request needs your personal API key. Generate one under Account Settings → API (logged in only, shown once — copy it). You can send it three ways:
1. Header (recommended): curl -H "X-API-Key: al_live_your_key_here" "https://artlair.eu/api/v1/posts?limit=5"
2. Query parameter: https://artlair.eu/api/v1/posts?limit=5&api_key=al_live_your_key_here
3. In the URL path (the key works anywhere in it — beginning or end):
https://artlair.eu/api/v1/al_live_your_key_here/posts?limit=5
https://artlair.eu/api/v1/posts/al_live_your_key_here?limit=5
Tip: the header is preferred — keys in URLs can end up in browser history and server logs. The URL forms are there for quick tests and simple integrations.
| Case | Response |
|---|---|
| Missing / invalid key | 401 — generate a fresh key in Settings |
| Suspended account or blocked key | 403 |
| Too many requests | 429 with a Retry-After header |
API Index
Machine-readable list of every endpoint — handy for discovering the API programmatically. Requires your API key.
curl https://artlair.eu/api/v1/
Posts
Lists public (approved) posts, newest first.
| Parameter | Optional | Description |
|---|---|---|
| page | yes | Page number, starts at 1. Default 1. |
| limit | yes | Items per page, 1–50. Default 20. |
| sort | yes | new (default), popular (most likes), views (most views). |
| category | yes | Filter by exact category name, e.g. category=Digital. |
| tag | yes | Filter by a single tag, e.g. tag=dragon. |
| user | yes | Only posts by that username. |
| q | yes | Free-text search across title and tags. |
curl "https://artlair.eu/api/v1/posts?sort=popular&limit=5"
{
"ok": true,
"data": [
{
"id": 42,
"title": "Sunset over the lair",
"category": "Digital",
"tags": ["sunset", "landscape"],
"media_type": "image",
"rating": "safe",
"is_ai": false,
"likes": 128,
"views": 940,
"created_at": "2026-09-20 14:32:10",
"url": "https://artlair.eu/media/image?id=42",
"thumb": "https://artlair.eu/media/thumb?f=...&w=400",
"author": {
"id": 7,
"username": "nullspark",
"profile_url": "https://artlair.eu/account/profile?u=nullspark"
}
}
],
"meta": { "page": 1, "limit": 5, "total": 412, "total_pages": 83 }
}
One approved post, including its description. 404 if the post doesn't exist or isn't public.
curl https://artlair.eu/api/v1/posts/42
Marketplace
Active marketplace items with prices in tokens.
| Parameter | Optional | Description |
|---|---|---|
| page / limit | yes | Pagination, same as posts. |
| sort | yes | new (default), popular (most purchases), price (cheapest first). |
| category | yes | Filter by exact category name. |
| q | yes | Free-text search across title and tags. |
curl "https://artlair.eu/api/v1/marketplace?sort=price&limit=10"
{
"ok": true,
"data": [
{
"id": 12,
"title": "Custom dragon banner",
"category": "Banners",
"tags": ["dragon", "banner"],
"price_tokens": 500,
"purchase_count": 3,
"created_at": "2026-09-18 10:05:44",
"preview_url": "https://artlair.eu/uploads/marketplace/previews/...",
"url": "https://artlair.eu/marketplace_item?id=12",
"seller": "nullspark"
}
],
"meta": { "page": 1, "limit": 10, "total": 27, "total_pages": 3 }
}
One marketplace item with full description, seller and current owner.
curl https://artlair.eu/api/v1/marketplace/12
Forum
All forum boards with their categories and thread counts.
curl https://artlair.eu/api/v1/forum/boards
Forum threads, pinned first. Pass board_id (from the boards endpoint) to filter to one board.
| Parameter | Optional | Description |
|---|---|---|
| board_id | yes | Only threads in this board. Omit for all boards. |
| page / limit | yes | Pagination, same as posts. |
curl "https://artlair.eu/api/v1/forum/threads?board_id=3&limit=10"
{
"ok": true,
"data": [
{
"id": 96,
"title": "Welcome to the forum!",
"board_id": 3,
"author": "admin",
"is_pinned": true,
"is_locked": false,
"reply_count": 14,
"views": 302,
"created_at": "2026-08-01 09:00:00",
"last_post_at": "2026-09-25 18:44:02",
"url": "https://artlair.eu/forum/thread?id=96"
}
],
"meta": { "page": 1, "limit": 10, "total": 57, "total_pages": 6 }
}
Users
Public profile and stats for one user. Only public data is exposed — never emails or private settings.
curl https://artlair.eu/api/v1/users/nullspark
{
"ok": true,
"data": {
"id": 7,
"username": "nullspark",
"avatar_url": "https://artlair.eu/uploads/avatars/...",
"joined": "2026-05-14 12:00:00",
"is_banned": false,
"stats": { "posts": 18, "likes": 512, "followers": 27, "following": 9 },
"url": "https://artlair.eu/account/profile?u=nullspark"
}
}
Notes
| Topic | Details |
|---|---|
| Errors | 400 bad request, 401 missing/invalid key, 403 blocked key or suspended account, 404 unknown endpoint / not found, 405 non-GET method, 429 rate limit exceeded, 500 server error. |
| Pagination | Every list endpoint accepts page and limit (max 50) and returns meta.total and meta.total_pages. |
| Auth | Personal API key (Settings → API). CORS-enabled (Access-Control-Allow-Origin: *), so it works from browsers too. |
| Rate limits | 120 requests/min per IP. Per key: 300 requests/hour and 2,000/day. Exceeding a limit 30 times in an hour auto-blocks the key for 6 hours. All requests are logged and monitored by site staff. |
| Caching | Responses may be cached for up to 60 seconds. Error responses are never cached. |
| Fallback URL | If clean URLs don't work on your server, the query form works too:/api/v1/index.php?endpoint=posts&id=42 |
Need an endpoint that doesn't exist yet, or spot a bug? Contact us via the contact page or email support@artlair.eu.