Demand API
Manage demand sources (DSPs), Delegate strategies, circuit breaker state, and demand-side configuration.
Base URL: https://api.praevis.com
Auth: X-API-Key: {YOUR_KEY} on all requests
Demand Sources
List demand sources
GET /api/demand/sourcesQuery params:
| Param | Values | Description |
|---|---|---|
status | active, sandbox, archived | Filter by status |
mode | rtb, delegate | Filter by integration mode |
Response:
{
"dsps": [
{
"id": "dsp-uuid",
"name": "Example DSP",
"mode": "delegate",
"status": "active",
"endpoint_url": null,
"sandbox": false,
"daily_budget_cents": 50000,
"created_at": "2026-01-10T09:00:00Z"
}
],
"total": 3
}Register demand source
POST /api/demand/sourcesBody:
{
"name": "My DSP",
"mode": "rtb",
"endpoint_url": "https://bidder.example.com/bid",
"sandbox": false,
"daily_budget_cents": 50000,
"timeout_ms": 150
}| Field | Required | Description |
|---|---|---|
name | ✓ | Display name |
mode | ✓ | rtb or delegate |
endpoint_url | RTB only | Bidder endpoint URL (must respond <150ms) |
sandbox | — | Start in sandbox mode |
daily_budget_cents | — | Daily spend cap in cents (0 = unlimited) |
timeout_ms | — | Custom timeout override (max 150ms) |
Response: 201 Created
Get demand source
GET /api/demand/sources/{id}Update demand source
PUT /api/demand/sources/{id}Partial update — only fields included are changed.
{
"daily_budget_cents": 75000,
"sandbox": false
}Get demand source metrics
GET /api/demand/sources/{id}/stats?period=24hResponse:
{
"dsp_id": "dsp-uuid",
"period": "24h",
"bid_requests": 284500,
"bids": 97200,
"wins": 42100,
"impressions": 41850,
"win_rate": 0.1480,
"spend_cents": 61983,
"avg_cpm_cents": 1481,
"timeout_rate": 0.0082,
"p50_ms": 38,
"p95_ms": 112
}Get demand source health
GET /api/demand/sources/{id}/healthResponse:
{
"circuit_breaker": "closed",
"timeout_rate_5m": 0.012,
"error_rate_5m": 0.003,
"avg_latency_ms": 42,
"qps_current": 87,
"qps_limit": 200,
"daily_budget_remaining_cents": 14230,
"last_bid_at": "2026-02-17T14:22:01Z"
}Circuit breaker states: closed (healthy), open (paused), half_open (recovering).
Update Delegate strategy
PUT /api/demand/sources/{id}/strategy
Content-Type: application/jsonBody: Full Delegate strategy JSON
{
"version": "1.0",
"dsp_id": "{id}",
"campaigns": [...],
"rules": [...],
"default_bid": 1.00
}Strategy takes effect within 30 seconds across all regions.
Response: 200 OK with the saved strategy.
Reset circuit breaker
POST /api/demand/sources/{id}/resetManually clears an open circuit breaker. Use after fixing the underlying latency issue.
Body: Empty.
Response: 200 OK
Loss Notifications
When your bid loses an auction, Praevis fires a POST to your lurl (loss notification URL) if provided in your bid response.
How it works
Include lurl in your bid response:
{
"id": "bid-1",
"impid": "1",
"price": 2.50,
"lurl": "https://dsp.example.com/loss?auction=${AUCTION_ID}&price=${AUCTION_PRICE}&reason=${AUCTION_LOSS}"
}Supported macros
| Macro | Replaced with |
|---|---|
${AUCTION_ID} | Auction request ID |
${AUCTION_PRICE} | Winning price (CPM) |
${AUCTION_LOSS} | Loss reason code |
Loss reason codes (OpenRTB Table 5.25)
| Code | Meaning |
|---|---|
100 | Bid was below auction floor |
102 | Lost to higher bid |
{ "circuit_breaker": "closed", "message": "Circuit breaker reset successfully" }Resetting while the latency issue persists will retrigger the circuit breaker within seconds. Fix the endpoint first.
Pool subscriptions
List pools subscribed to
GET /api/demand/sources/{id}/poolsResponse:
{
"pools": [
{ "id": "pool-uuid", "name": "Premium CTV", "publisher_count": 8 }
]
}Subscribe to pool
POST /api/demand/sources/{id}/pools/{pool_id}Empty body. Returns 200 OK.
Unsubscribe from pool
DELETE /api/demand/sources/{id}/pools/{pool_id}Returns 200 OK.