API Reference

The Veraj Media REST API lets you manage creatives, campaigns, analytics, and ad zones programmatically. All requests use JSON and require authentication.

Overview

The API is organized around REST principles. All requests should be made to:

https://api.verajohn-media.com/v1

All request and response bodies are encoded as JSON. Use the Content-Type: application/json header for requests with a body.

The API supports GET, POST, PUT, PATCH, and DELETE methods. All timestamps are returned in UTC as ISO 8601 strings. Resource IDs are prefixed strings (e.g. cr_, cmp_, zn_) and are immutable once created.

Authentication

Authenticate by including your API key in the Authorization header of every request.

# Example request curl https://api.verajohn-media.com/v1/creatives \ -H "Authorization: Bearer YOUR_API_KEY"

API keys can be generated from your account dashboard under Settings → API Keys. Each key is scoped to your organization and can be assigned one of three permission levels:

ScopeAccess
readRead-only access to all resources
writeRead and write access to all resources
adminFull access including user management and billing

Keep your key secret — do not expose it in client-side code. If a key is compromised, revoke it immediately from your dashboard.

Errors

The API uses standard HTTP status codes. Errors return a JSON body with a message field and an optional code for programmatic handling.

{ "error": { "status": 404, "code": "resource_not_found", "message": "Creative not found", "request_id": "req_a1b2c3d4" } }
StatusMeaning
200Success
201Resource created
204Deleted successfully (no body returned)
400Bad request — check your parameters
401Unauthorized — invalid or missing API key
403Forbidden — your key lacks the required scope
404Resource not found
409Conflict — resource already exists or state mismatch
422Unprocessable entity — validation failed
429Rate limit exceeded
500Internal server error
503Service unavailable — try again shortly

Every response includes a X-Request-Id header. Include this value when contacting support about a specific request.

Rate Limits

API requests are rate-limited per API key. The current limits are:

PlanLimitBurst
Starter100 requests / minute20 concurrent
Growth500 requests / minute50 concurrent
Enterprise2,000 requests / minute200 concurrent

Rate limit information is included in every response via headers:

X-RateLimit-Limit: 500 X-RateLimit-Remaining: 487 X-RateLimit-Reset: 1711612800

When you exceed the limit, you'll receive a 429 response. The Retry-After header tells you how many seconds to wait before retrying.

Pagination

All list endpoints return paginated results. Use page and per_page query parameters to navigate results.

# Fetch page 3 with 50 results per page curl https://api.verajohn-media.com/v1/creatives?page=3&per_page=50 \ -H "Authorization: Bearer YOUR_API_KEY"

Every paginated response includes a pagination object:

{ "data": [...], "pagination": { "page": 3, "per_page": 50, "total": 247, "total_pages": 5 } }

The default page size is 25. The maximum is 100. Requesting beyond the last page returns an empty data array.

Versioning

The API is versioned via the URL path. The current version is v1. When breaking changes are introduced, a new version will be released and the previous version will remain supported for at least 12 months.

Non-breaking changes (new fields, new endpoints, new optional parameters) are added to the current version without a version bump. Build your integration to tolerate unknown JSON fields.

Creatives

Upload and manage ad creatives — images, HTML5 banners, and video assets. Creatives are the visual content served inside ad zones.

GET /v1/creatives List all creatives

Returns a paginated list of creatives in your account.

Query Parameters

NameTypeDescription
pageintegerOptional. Page number (default: 1)
per_pageintegerOptional. Results per page (default: 25, max: 100)
typestringOptional. Filter by type: image, html5, video
statusstringOptional. Filter: active, archived, pending_review
searchstringOptional. Search by name (case-insensitive partial match)
sortstringOptional. Sort field: created_at, name, impressions (default: created_at)
orderstringOptional. asc or desc (default: desc)

Response

{ "data": [ { "id": "cr_8xK2mP", "name": "Summer Banner 300x250", "type": "image", "status": "active", "width": 300, "height": 250, "file_size": 48210, "url": "https://cdn.verajohn-media.com/cr_8xK2mP.png", "click_url": "https://example.com/landing", "tags": ["summer", "promo"], "created_at": "2026-03-15T10:30:00Z", "updated_at": "2026-03-18T14:22:00Z" } ], "pagination": { "page": 1, "per_page": 25, "total": 42, "total_pages": 2 } }
POST /v1/creatives Upload a creative

Upload a new creative asset. Send as multipart/form-data. Maximum file size is 10 MB for images, 2 MB for HTML5, and 50 MB for video.

Body Parameters

NameTypeDescription
namestringRequired. Display name (max 120 characters)
filefileRequired. The creative file (PNG, JPG, GIF, HTML, MP4, WEBM)
click_urlstringOptional. Click-through destination URL
tagsarrayOptional. Array of string tags for organization
alt_textstringOptional. Accessibility alt text for the creative

Response

// 201 Created { "id": "cr_9yL3nQ", "name": "Holiday Video 16:9", "type": "video", "status": "pending_review", "width": 1920, "height": 1080, "file_size": 4821034, "url": "https://cdn.verajohn-media.com/cr_9yL3nQ.mp4", "created_at": "2026-03-28T09:15:00Z" }
GET /v1/creatives/:id Get a creative

Retrieve a single creative by its ID. Returns the full creative object including all metadata and current delivery status.

PUT /v1/creatives/:id Update a creative

Update a creative's metadata. You cannot replace the file itself — upload a new creative instead.

Body Parameters

NameTypeDescription
namestringOptional. Updated display name
click_urlstringOptional. Updated click-through URL
tagsarrayOptional. Replace tags (send full array)
alt_textstringOptional. Updated alt text
POST /v1/creatives/:id/archive Archive a creative

Archive a creative. Archived creatives stop serving but are not deleted. Use POST /v1/creatives/:id/unarchive to restore.

POST /v1/creatives/:id/duplicate Duplicate a creative

Create a copy of an existing creative with a new ID. The file is shared — no additional storage is used. Optionally override metadata in the request body.

Body Parameters

NameTypeDescription
namestringOptional. Name for the copy (default: original name + " (copy)")
DELETE /v1/creatives/:id Delete a creative

Permanently delete a creative and its hosted file. This also removes it from any campaigns it was assigned to. Returns 204 No Content on success. This action cannot be undone.

Campaigns

Create and manage advertising campaigns. A campaign groups creatives, targeting rules, budget, and scheduling into a single deliverable unit.

GET /v1/campaigns List campaigns

Returns a paginated list of campaigns.

Query Parameters

NameTypeDescription
statusstringOptional. Filter: draft, active, paused, ended
searchstringOptional. Search by campaign name
pageintegerOptional. Page number
per_pageintegerOptional. Results per page (default: 25, max: 100)

Response

{ "data": [ { "id": "cmp_3nR7vQ", "name": "Spring Sale 2026", "status": "active", "budget_daily": 150.00, "budget_total": 4500.00, "spent": 1230.45, "start_date": "2026-03-01", "end_date": "2026-03-31", "creative_count": 4, "created_at": "2026-02-28T16:00:00Z" } ], "pagination": { ... } }
POST /v1/campaigns Create a campaign

Create a new campaign. Campaigns are created in draft status. Use the activate endpoint to start delivery.

Body Parameters

NameTypeDescription
namestringRequired. Campaign name
creative_idsarrayRequired. Array of creative IDs to include
zone_idsarrayOptional. Target specific ad zones
audience_idstringOptional. Audience segment to target
budget_dailynumberOptional. Daily budget cap in USD
budget_totalnumberOptional. Total lifetime budget in USD
bid_cpmnumberOptional. Maximum CPM bid (default: auto-optimized)
start_datestringOptional. ISO 8601 start date
end_datestringOptional. ISO 8601 end date
frequency_capobjectOptional. { "max": 3, "period": "day" }
GET /v1/campaigns/:id Get a campaign

Retrieve a single campaign with full configuration, budget details, and current spend.

PUT /v1/campaigns/:id Update a campaign

Update an existing campaign's settings, creatives, targeting, or budget. Changes to active campaigns take effect within 60 seconds.

POST /v1/campaigns/:id/activate Activate a campaign

Move a campaign from draft or paused to active. The campaign must have at least one approved creative and a valid budget.

POST /v1/campaigns/:id/pause Pause a campaign

Pause an active campaign. Delivery stops immediately. The campaign retains all settings and can be reactivated.

DELETE /v1/campaigns/:id Delete a campaign

Permanently delete a campaign. Active campaigns must be paused first. Analytics data is retained for 90 days after deletion.

Ad Zones

Manage ad zones — the placement slots on publisher sites where creatives are displayed. Each zone has a fixed size and belongs to a single domain.

GET /v1/zones List ad zones

Returns all ad zones available in your network.

Query Parameters

NameTypeDescription
domainstringOptional. Filter by publisher domain
sizestringOptional. Filter by size, e.g. 300x250
pageintegerOptional. Page number

Response

{ "data": [ { "id": "zn_4kW9pR", "name": "Homepage Leaderboard", "size": "728x90", "domain": "example-publisher.com", "status": "active", "fill_rate": 0.94, "embed_code": "<script src=\"https://cdn.verajohn-media.com/serve/zn_4kW9pR.js\"></script>", "created_at": "2026-01-10T08:00:00Z" } ], "pagination": { ... } }
POST /v1/zones Create an ad zone

Register a new ad zone for a publisher site. An embed code is generated automatically upon creation.

Body Parameters

NameTypeDescription
namestringRequired. Zone display name
sizestringRequired. Dimensions, e.g. 300x250, 728x90, 970x250
domainstringRequired. Publisher domain
floor_cpmnumberOptional. Minimum CPM price for this zone
allowed_typesarrayOptional. Allowed creative types: ["image", "html5"] (default: all)
GET /v1/zones/:id Get an ad zone

Retrieve a single ad zone by ID, including its embed code and current fill rate.

PUT /v1/zones/:id Update an ad zone

Update a zone's name, floor price, or allowed creative types. Size and domain cannot be changed after creation.

DELETE /v1/zones/:id Delete an ad zone

Delete an ad zone. The embed code will stop serving ads immediately. Active campaigns targeting this zone will be updated automatically.

Audiences

Define audience segments for campaign targeting. Audiences are built from rules based on geography, device, browser, language, and custom key-value pairs.

GET /v1/audiences List audiences

Returns all audience segments in your account with estimated reach.

POST /v1/audiences Create an audience

Create a new audience segment using targeting rules.

Body Parameters

NameTypeDescription
namestringRequired. Audience name
rulesarrayRequired. Array of targeting rule objects
matchstringOptional. all (AND) or any (OR) — default: all

Rule Object

{ "field": "geo.country", "operator": "in", "value": ["US", "CA", "GB"] }

Supported fields: geo.country, geo.region, geo.city, device.type (desktop, mobile, tablet), device.os, browser.name, language, custom.*.

Supported operators: eq, neq, in, not_in, contains, starts_with.

GET /v1/audiences/:id Get an audience

Retrieve a single audience with its rules and current estimated reach.

PUT /v1/audiences/:id Update an audience

Update an audience's name or targeting rules. Changes propagate to active campaigns using this audience within 5 minutes.

DELETE /v1/audiences/:id Delete an audience

Delete an audience segment. Campaigns using this audience will fall back to untargeted delivery.

Scheduling

Control when campaigns deliver with dayparting schedules. Assign a schedule to a campaign to restrict delivery to specific hours and days of the week.

GET /v1/schedules List schedules

Returns all dayparting schedules in your account.

POST /v1/schedules Create a schedule

Create a dayparting schedule. Specify active time windows by day-of-week and hour ranges.

Body Parameters

NameTypeDescription
namestringRequired. Schedule name
timezonestringRequired. IANA timezone, e.g. America/New_York
windowsarrayRequired. Array of time window objects

Window Object

{ "days": ["mon", "tue", "wed", "thu", "fri"], "start_hour": 9, "end_hour": 17 }

Hours are in 24-hour format (0–23). A window from start_hour: 9 to end_hour: 17 means delivery from 9:00 AM to 5:00 PM in the specified timezone.

POST /v1/campaigns/:id/schedule Attach schedule to campaign

Attach a dayparting schedule to a campaign. Only one schedule can be active per campaign. Pass { "schedule_id": null } to remove.

Body Parameters

NameTypeDescription
schedule_idstringRequired. Schedule ID or null to detach
DELETE /v1/schedules/:id Delete a schedule

Delete a schedule. It is automatically detached from any campaigns that reference it.

Analytics

Retrieve real-time and historical performance data for your campaigns, creatives, and zones.

GET /v1/analytics/campaigns/:id Campaign performance

Get aggregated performance metrics for a campaign over a date range.

Query Parameters

NameTypeDescription
startstringRequired. Start date (YYYY-MM-DD)
endstringRequired. End date (YYYY-MM-DD)
granularitystringOptional. hour, day, week (default: day)

Response

{ "campaign_id": "cmp_3nR7vQ", "impressions": 148230, "clicks": 5204, "ctr": 0.0351, "spend": 742.15, "ecpm": 5.01, "data": [ { "date": "2026-03-15", "impressions": 21176, "clicks": 743, "spend": 106.02 } ] }
GET /v1/analytics/creatives/:id Creative performance

Get performance metrics for a single creative across all campaigns. Accepts the same start, end, and granularity parameters as campaign analytics.

GET /v1/analytics/zones/:id Zone performance

Get performance and fill-rate metrics for a specific ad zone. Useful for publishers monitoring inventory utilization.

Response

{ "zone_id": "zn_4kW9pR", "requests": 320400, "impressions": 301176, "fill_rate": 0.94, "clicks": 9840, "revenue": 1508.82 }
GET /v1/analytics/overview Account overview

Get a high-level summary of your account's performance across all campaigns for the given date range. Includes total impressions, clicks, spend, and top-performing campaigns.

Query Parameters

NameTypeDescription
startstringRequired. Start date (YYYY-MM-DD)
endstringRequired. End date (YYYY-MM-DD)
GET /v1/analytics/campaigns/:id/geo Geographic breakdown

Get a geographic breakdown of impressions and clicks for a campaign, grouped by country. Accepts the same start and end parameters.

Response

{ "campaign_id": "cmp_3nR7vQ", "countries": [ { "code": "US", "impressions": 84200, "clicks": 3102 }, { "code": "GB", "impressions": 31400, "clicks": 1048 }, { "code": "CA", "impressions": 18630, "clicks": 621 } ] }

Reports

Generate and download CSV or JSON reports for offline analysis. Reports are built asynchronously and available for download once complete.

POST /v1/reports Create a report

Request a new report. The report is generated in the background. Poll the report status or subscribe to the report.completed webhook event.

Body Parameters

NameTypeDescription
typestringRequired. Report type: campaign_summary, creative_breakdown, zone_performance, geo_report
startstringRequired. Start date (YYYY-MM-DD)
endstringRequired. End date (YYYY-MM-DD)
formatstringOptional. csv or json (default: csv)
campaign_idsarrayOptional. Limit to specific campaigns

Response

// 202 Accepted { "id": "rpt_7mT4xN", "status": "processing", "created_at": "2026-03-28T12:00:00Z" }
GET /v1/reports/:id Get report status

Check the status of a report. When status is completed, a download_url is included. Download URLs expire after 24 hours.

Response

{ "id": "rpt_7mT4xN", "status": "completed", "download_url": "https://cdn.verajohn-media.com/reports/rpt_7mT4xN.csv?token=...", "expires_at": "2026-03-29T12:00:00Z", "rows": 1847 }
GET /v1/reports List reports

List all reports in your account, ordered by creation date. Completed reports include their download URL if still valid.

Webhooks

Subscribe to real-time event notifications. When an event occurs, Veraj Media sends a POST request to your configured URL with a JSON payload.

GET /v1/webhooks List webhooks

Returns all registered webhook endpoints.

POST /v1/webhooks Create a webhook

Register a new webhook endpoint to receive event notifications.

Body Parameters

NameTypeDescription
urlstringRequired. HTTPS endpoint URL
eventsarrayRequired. Event types to subscribe to
secretstringOptional. Signing secret for payload verification (auto-generated if omitted)

Available Events

EventDescription
campaign.activatedCampaign started delivering
campaign.pausedCampaign was paused
campaign.endedCampaign reached its end date or budget cap
campaign.budget_warningCampaign has used 80% of its total budget
creative.approvedCreative passed review and is ready to serve
creative.rejectedCreative was rejected during review
report.completedAsync report is ready for download
zone.low_fillZone fill rate dropped below 50%

Payload Format

{ "id": "evt_9cN2kP", "type": "campaign.ended", "created_at": "2026-03-28T23:59:00Z", "data": { "campaign_id": "cmp_3nR7vQ", "reason": "budget_exhausted", "total_spend": 4500.00 } }

Payloads are signed with HMAC-SHA256 using your webhook secret. Verify the X-Signature header to ensure authenticity.

PUT /v1/webhooks/:id Update a webhook

Update a webhook's URL, subscribed events, or signing secret.

POST /v1/webhooks/:id/test Send test event

Send a test event to your webhook endpoint. Returns the HTTP status code your server responded with.

DELETE /v1/webhooks/:id Delete a webhook

Delete a webhook endpoint. Events will no longer be delivered to this URL.

Users & API Keys

Manage team members and API keys for your organization. Requires admin scope.

GET /v1/users List users

Returns all team members in your organization with their roles and last active date.

Response

{ "data": [ { "id": "usr_2bK8rT", "email": "alice@example.com", "name": "Alice Chen", "role": "admin", "last_active": "2026-03-27T18:45:00Z" } ] }
POST /v1/users/invite Invite a user

Send an invitation email to a new team member.

Body Parameters

NameTypeDescription
emailstringRequired. Email address
rolestringOptional. admin, editor, or viewer (default: viewer)
DELETE /v1/users/:id Remove a user

Remove a user from your organization. Their API keys are automatically revoked.

GET /v1/api-keys List API keys

Returns all API keys in your organization. Key values are masked except the last 4 characters.

POST /v1/api-keys Create an API key

Generate a new API key. The full key value is only returned once in the response — store it securely.

Body Parameters

NameTypeDescription
namestringRequired. Descriptive label for the key
scopestringOptional. read, write, or admin (default: read)
expires_atstringOptional. ISO 8601 expiration date (default: never)

Response

// 201 Created — store the key now, it won't be shown again { "id": "key_5nQ3wM", "name": "Production Server", "key": "jm_live_a1b2c3d4e5f6g7h8i9j0...", "scope": "write", "created_at": "2026-03-28T10:00:00Z" }
DELETE /v1/api-keys/:id Revoke an API key

Permanently revoke an API key. Any requests using this key will immediately start receiving 401 Unauthorized.

Billing

View billing information, invoices, and current usage. Requires admin scope.

GET /v1/billing Get billing summary

Returns your current plan, billing cycle, and usage for the current period.

Response

{ "plan": "growth", "billing_cycle": "monthly", "current_period": { "start": "2026-03-01", "end": "2026-03-31" }, "usage": { "impressions": 1240000, "spend": 3720.50, "storage_mb": 842 } }
GET /v1/billing/invoices List invoices

Returns a list of past invoices with amounts, status, and PDF download links.

Response

{ "data": [ { "id": "inv_8pR2mK", "period": "2026-02", "amount": 2890.00, "currency": "USD", "status": "paid", "pdf_url": "https://cdn.verajohn-media.com/invoices/inv_8pR2mK.pdf", "paid_at": "2026-03-01T00:05:00Z" } ] }
GET /v1/billing/usage Get detailed usage

Get day-by-day usage breakdown for the current billing period, including impressions served, bandwidth, and storage.

Query Parameters

NameTypeDescription
startstringOptional. Start date (defaults to current period start)
endstringOptional. End date (defaults to today)