API Documentation
AdServerX REST API — v1
Contents
Authentication
All protected API endpoints require a Bearer token in the Authorization header.
Authorization: Bearer YOUR_API_KEY
To obtain an API key:
- Use
POST /api/v1/auth/loginwith your credentials to get a key programmatically, or - Generate one from the API Keys page in your account.
API keys are stored as SHA256 hashes — the raw key is shown only once at creation time.
Error Responses
All responses are JSON. Errors follow this format:
{
"success": false,
"error": "Description of the error"
}
| HTTP Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created |
| 400 | Bad request / business rule violation |
| 401 | Missing or invalid API key |
| 403 | Forbidden |
| 404 | Resource not found |
| 422 | Validation error |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
| 501 | Not implemented |
Rate Limits
| Route Group | Limit |
|---|---|
| Auth login | 5 requests / 15 minutes |
Ad serving (/api/v1/serve/*) | 1000 requests / minute |
General API (/api/v1/*) | 60 requests / minute (configurable) |
Rate limits are per IP address. When exceeded, the API returns HTTP 429.
Auth Endpoints
POST /api/v1/auth/login
Authenticate and receive an API key. No Bearer token required.
Request body:
{
"email": "user@example.com",
"password": "your_password",
"name": "My App Key" // optional label
}
Response (201):
{
"success": true,
"api_key": "ak_a1b2c3d4e5f6...",
"key_prefix": "ak_a1b2c3",
"message": "Store this API key securely — it will not be shown again."
}
POST /api/v1/auth/logout
Revoke the API key used in this request. Requires Bearer token.
Response (200):
{ "success": true, "message": "API key revoked." }
Campaign Endpoints
All campaign endpoints require Authorization: Bearer {key}
GET /api/v1/campaigns
List your campaigns.
Query params: page, per_page (max 100), status
{
"success": true,
"data": [ { "id": 1, "name": "My Campaign", "status": "active", ... } ],
"pagination": { "page": 1, "per_page": 25, "count": 1 }
}
GET /api/v1/campaigns/{id}
Get a single campaign.
POST /api/v1/campaigns
Create a campaign.
{
"name": "Summer Sale",
"bid_amount": "1.50",
"daily_budget": "50.00",
"start_date": "2026-03-10",
"end_date": null
}
PUT /api/v1/campaigns/{id}
Update a campaign. Send only the fields you want to change.
DELETE /api/v1/campaigns/{id}
Delete a campaign.
Ad Endpoints
All ad endpoints require Authorization: Bearer {key}
GET /api/v1/ads
List your ads. Filter with ?campaign_id=123, ?status=active.
GET /api/v1/ads/{id}
Get a single ad.
POST /api/v1/ads
Create an ad.
{
"campaign_id": 1,
"name": "Banner Ad 300x250",
"type": "banner",
"headline": "Click Here",
"destination_url": "https://example.com",
"image_url": "https://cdn.example.com/banner.jpg",
"width": 300,
"height": 250
}
PUT /api/v1/ads/{id}
Update an ad.
DELETE /api/v1/ads/{id}
Delete an ad.
Analytics Endpoints
All analytics endpoints require Authorization: Bearer {key}
GET /api/v1/analytics/campaigns/{id}
Get stats for a campaign.
Query params: period — one of today, yesterday, last_7_days, last_30_days, all (default: all)
{
"success": true,
"data": {
"campaign_id": 1,
"period": "last_7_days",
"stats": { "impressions": 5000, "clicks": 120, "ctr": 2.4, ... },
"daily_trend": [ { "date": "2026-03-09", "impressions": 700, ... } ]
}
}
GET /api/v1/analytics/ads/{id}
Get stats for an ad. Same period param as above.
GET /api/v1/analytics/publishers/{id}
Get stats for a publisher. Same period param as above.
GET /api/v1/analytics/zones/{id}
Zone-level analytics are not yet implemented. Returns HTTP 501.
Publisher Endpoints
Requires Authorization: Bearer {key}. Create and delete are admin-only.
GET /api/v1/publishers
List publishers. Admins see all; publisher-role users see their own record.
Query params: page, per_page (max 100)
GET /api/v1/publishers/{id}
Get a single publisher.
GET /api/v1/publishers/{id}/analytics
Get publisher stats.
Query params: period — today, yesterday, last_7_days, last_30_days, all
POST /api/v1/publishers Admin
Create a publisher.
{
"name": "My Publisher",
"user_id": 5,
"website_url": "https://example.com",
"description": "Optional description"
}
PUT /api/v1/publishers/{id}
Update a publisher. Admins can update any; publisher users can update their own.
DELETE /api/v1/publishers/{id} Admin
Delete a publisher.
Website Endpoints
Requires Authorization: Bearer {key}. Access is scoped to the caller's publisher.
GET /api/v1/websites
List websites. Filter with ?publisher_id=1.
Query params: publisher_id, page, per_page
GET /api/v1/websites/{id}
Get a single website.
POST /api/v1/websites
Create a website. The caller must own the specified publisher_id.
{
"publisher_id": 1,
"name": "My Site",
"url": "https://mysite.com",
"category": "news"
}
PUT /api/v1/websites/{id}
Update a website.
DELETE /api/v1/websites/{id}
Delete a website.
Zone Endpoints
Requires Authorization: Bearer {key}. Access is scoped to the caller's publisher.
GET /api/v1/zones
List zones. Filter with ?website_id=1.
Query params: website_id, page, per_page
GET /api/v1/zones/{id}
Get a single zone.
POST /api/v1/zones
Create a zone. The caller must own the specified website_id's publisher.
{
"website_id": 1,
"name": "Header Banner",
"type": "banner",
"width": 728,
"height": 90
}
PUT /api/v1/zones/{id}
Update a zone.
DELETE /api/v1/zones/{id}
Delete a zone.
Webhook Endpoints
Requires Authorization: Bearer {key}. Webhooks are identified by UUID.
GET /api/v1/webhooks
List your webhooks.
GET /api/v1/webhooks/{uuid}
Get a single webhook. The signing secret is never returned after creation.
POST /api/v1/webhooks
Create a webhook. The signing secret is returned once in this response only.
{
"name": "My Webhook",
"url": "https://example.com/webhook",
"events": "campaign.created,ad.created", // comma-separated string or JSON array
"is_active": 1
}
Response (201):
{
"success": true,
"data": { "uuid": "...", "name": "My Webhook", ... },
"secret": "whsec_...",
"message": "Webhook created. Store the secret securely — it will not be shown again."
}
Available events: campaign.created, campaign.status_changed, campaign.deleted, ad.created, ad.status_changed, payment.completed, payment.failed, publisher.approved, publisher.rejected, fraud.alert, webhook.test
Signature verification: Each delivery includes an X-AdServerX-Signature: sha256=... header computed with HMAC-SHA256 over the raw request body using your webhook secret.
PUT /api/v1/webhooks/{uuid}
Update a webhook.
DELETE /api/v1/webhooks/{uuid}
Delete a webhook.
POST /api/v1/webhooks/{uuid}/test
Dispatch a webhook.test event to verify your endpoint is reachable.
Reports Endpoints
Requires Authorization: Bearer {key}.
GET /api/v1/reports
Summary financial report. Non-admins see their own data; admins see platform-wide data.
Query params: period — today, yesterday, last_7_days, last_30_days, all
{
"success": true,
"data": {
"period": "last_7_days",
"summary": { "total_revenue": "1234.56", "total_impressions": 50000, ... },
"revenue_over_time": [ { "date": "2026-03-09", "revenue": "180.00" }, ... ]
}
}
GET /api/v1/reports/financial Admin
Full financial report including per-advertiser revenue and per-publisher payouts.
{
"success": true,
"data": {
"period": "all",
"summary": { ... },
"revenue_over_time": [ ... ],
"per_advertiser_revenue": [ ... ],
"per_publisher_payouts": [ ... ]
}
}
Invoice Endpoints
Requires Authorization: Bearer {key}. Read-only — invoice management is handled via the web UI.
GET /api/v1/invoices
List invoices. Admins see all; others see their own.
Query params: page, per_page
GET /api/v1/invoices/{uuid}
Get a single invoice with line items and transactions.
{
"success": true,
"data": {
"uuid": "...",
"status": "paid",
"total": "99.00",
"items": [ { "description": "Campaign impressions", "amount": "99.00" } ],
"transactions": [ { "type": "payment", "amount": "99.00", "created_at": "..." } ]
}
}
User Endpoints Admin Only
All user endpoints require Authorization: Bearer {key} with an admin account. Returns 403 for non-admins.
GET /api/v1/users
List all users.
Query params: page, per_page
GET /api/v1/users/{id}
Get a single user. Password hash is never returned.
POST /api/v1/users
Create a user.
{
"name": "Jane Doe",
"email": "jane@example.com",
"password": "SecurePass123!",
"role_id": 4
}
PUT /api/v1/users/{id}
Update a user. Omit password to leave it unchanged.
DELETE /api/v1/users/{id}
Soft-delete a user. Cannot delete your own account.
Settings Endpoints Admin Only
Requires Authorization: Bearer {key} with an admin account. Returns 403 for non-admins. Sensitive values (SMTP passwords, Stripe/PayPal keys) are masked in responses.
GET /api/v1/settings
Get all platform settings as a key/value object.
{
"success": true,
"data": {
"site_name": "AdServerX",
"currency": "USD",
"smtp_password": "********",
...
}
}
PUT /api/v1/settings
Update one or more settings. Send only the keys you want to change.
{ "site_name": "My Ad Network", "currency": "EUR" }
Ad Serving (Public)
No authentication required. Returns the best ad for a zone.
GET /api/v1/serve/{zone_uuid}
Query params: device, browser, os, country, region
GET /api/v1/serve/550e8400-e29b-41d4-a716-446655440000
?device=mobile&country=US
Tracking (Public)
No authentication required. CORS enabled for cross-origin requests.
POST /api/v1/track/impression
{ "zone_uuid": "...", "ad_uuid": "..." }
GET /api/v1/track/impression/pixel
1×1 pixel tracking. Returns a transparent GIF.
GET /api/v1/track/impression/pixel?zone_uuid=...&ad_uuid=...
POST /api/v1/track/click
{ "ad_uuid": "...", "impression_uuid": "...", "destination_url": "https://..." }
POST /api/v1/track/conversion
{ "click_uuid": "...", "type": "sale", "value": "29.99" }