The basics: every endpoint answers with JSON. Successful responses look like {"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.

CaseResponse
Missing / invalid key401 — generate a fresh key in Settings
Suspended account or blocked key403
Too many requests429 with a Retry-After header

API Index

GET https://artlair.eu/api/v1/

Machine-readable list of every endpoint — handy for discovering the API programmatically. Requires your API key.

curl https://artlair.eu/api/v1/

Posts

GET https://artlair.eu/api/v1/posts

Lists public (approved) posts, newest first.

ParameterOptionalDescription
pageyesPage number, starts at 1. Default 1.
limityesItems per page, 1–50. Default 20.
sortyesnew (default), popular (most likes), views (most views).
categoryyesFilter by exact category name, e.g. category=Digital.
tagyesFilter by a single tag, e.g. tag=dragon.
useryesOnly posts by that username.
qyesFree-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 } }
GET https://artlair.eu/api/v1/posts/{id}

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

GET https://artlair.eu/api/v1/marketplace

Active marketplace items with prices in tokens.

ParameterOptionalDescription
page / limityesPagination, same as posts.
sortyesnew (default), popular (most purchases), price (cheapest first).
categoryyesFilter by exact category name.
qyesFree-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 } }
GET https://artlair.eu/api/v1/marketplace/{id}

One marketplace item with full description, seller and current owner.

curl https://artlair.eu/api/v1/marketplace/12

Forum

GET https://artlair.eu/api/v1/forum/boards

All forum boards with their categories and thread counts.

curl https://artlair.eu/api/v1/forum/boards
GET https://artlair.eu/api/v1/forum/threads

Forum threads, pinned first. Pass board_id (from the boards endpoint) to filter to one board.

ParameterOptionalDescription
board_idyesOnly threads in this board. Omit for all boards.
page / limityesPagination, 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

GET https://artlair.eu/api/v1/users/{username}

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

TopicDetails
Errors400 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.
PaginationEvery list endpoint accepts page and limit (max 50) and returns meta.total and meta.total_pages.
AuthPersonal API key (Settings → API). CORS-enabled (Access-Control-Allow-Origin: *), so it works from browsers too.
Rate limits120 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.
CachingResponses may be cached for up to 60 seconds. Error responses are never cached.
Fallback URLIf 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.