AdCrew Exchange

Integration Guide

How to send CTV, mobile in-app and web inventory to the AdCrew Exchange and receive a bid.

Protocol
OpenRTB 2.6
Endpoint
exchange.adcrew.co
Version
7 · Sept 2026

Audience: developers integrating an SSP, ad server, publisher backend or SSAI service with AdCrew. This is a server-to-server supply integration. A website, app or player uses its backend or an agreed ad-serving integration; authentication secrets must not be embedded in browser code, apps or public ad tags.

From your side AdCrew is demand: send an eligible impression opportunity to one endpoint and receive a bid under our adcrew seat. AdCrew manages its downstream demand connections, the supplier-net bid and the agreed creative and measurement path.

POSThttps://exchange.adcrew.co/rtb/v1/auction

URL-token accounts receive an issued endpoint such as https://exchange.adcrew.co/rtb/v1/auction/adx_<token>. Health: GET https://exchange.adcrew.co/health. A successful health response is a service check, not a demand-availability or revenue guarantee.

Use HTTPS, Content-Type: application/json and X-OpenRTB-Version: 2.6. Send an identifying HTTP User-Agent, for example YourSSP-RTB/1.4. It identifies your calling service; device.ua inside the JSON describes the actual viewer device. Do not replace one with the other.

If an edge security page reports 1010 or another non-JSON rejection, send its reference and UTC timestamp to your AdCrew contact. Edge rejection and application authentication are different checks. The connection sheet records any agreed edge configuration.

1Quick start

Start with the sandbox connection sheet and download one of the complete request examples below. The samples use test: 1, fictional inventory, reserved documentation IPs and no advertising identifier. They require a sandbox account configured for these fixtures and direct owned-and-operated supply.

CTV · Roku

This example represents a Roku TV. The numeric app identifier and Roku store URL describe the same illustrative channel. The sandbox fixture uses a direct account, so the incoming schain is omitted by agreement; see §6.

{
  "id": "sandbox-roku-001",
  "test": 1,
  "at": 1,
  "cur": [
    "USD"
  ],
  "tmax": 500,
  "app": {
    "id": "sample-roku-channel",
    "name": "Example Channel",
    "bundle": "123456",
    "storeurl": "https://channelstore.roku.com/details/123456/example-channel",
    "publisher": {
      "id": "publisher-001",
      "name": "Example Media",
      "domain": "example.com"
    },
    "content": {
      "id": "sample-episode-001",
      "title": "Sample Documentary",
      "series": "Example Series",
      "season": "1",
      "episode": 1,
      "genre": "Documentary",
      "livestream": 0,
      "len": 1800,
      "language": "en",
      "contentrating": "TV-PG"
    }
  },
  "imp": [
    {
      "id": "1",
      "tagid": "sample-roku-preroll",
      "secure": 1,
      "bidfloor": 1.0,
      "bidfloorcur": "USD",
      "video": {
        "mimes": [
          "video/mp4"
        ],
        "protocols": [
          2,
          3,
          5,
          6,
          7,
          8
        ],
        "plcmt": 1,
        "linearity": 1,
        "startdelay": 0,
        "minduration": 6,
        "maxduration": 30,
        "w": 1920,
        "h": 1080,
        "api": [],
        "skip": 0
      }
    }
  ],
  "device": {
    "ua": "Roku/DVP-12.0 (12.0.0.4182-45)",
    "ip": "198.51.100.24",
    "devicetype": 3,
    "os": "Roku OS",
    "osv": "12.0",
    "lmt": 1,
    "geo": {
      "country": "USA",
      "type": 2
    }
  },
  "source": {
    "fd": 1,
    "tid": "326fe34d-d1da-46a1-9372-3d396e3c6001"
  },
  "regs": {
    "coppa": 0
  }
}
Android TV · complete request

The app bundle, store listing and device all describe Android TV. This is a complete request, not a replacement fragment that drops required device fields.

{
  "id": "sandbox-android-tv-001",
  "test": 1,
  "at": 1,
  "cur": [
    "USD"
  ],
  "tmax": 500,
  "app": {
    "id": "sample-android-tv",
    "name": "Example TV",
    "bundle": "com.example.tv",
    "storeurl": "https://play.google.com/store/apps/details?id=com.example.tv",
    "publisher": {
      "id": "publisher-001",
      "name": "Example Media",
      "domain": "example.com"
    },
    "content": {
      "id": "sample-episode-001",
      "title": "Sample Documentary",
      "series": "Example Series",
      "season": "1",
      "episode": 1,
      "genre": "Documentary",
      "livestream": 0,
      "len": 1800,
      "language": "en",
      "contentrating": "TV-PG"
    }
  },
  "imp": [
    {
      "id": "1",
      "tagid": "sample-android-tv-preroll",
      "secure": 1,
      "bidfloor": 1.0,
      "bidfloorcur": "USD",
      "video": {
        "mimes": [
          "video/mp4"
        ],
        "protocols": [
          2,
          3,
          5,
          6,
          7,
          8
        ],
        "plcmt": 1,
        "linearity": 1,
        "startdelay": 0,
        "minduration": 6,
        "maxduration": 30,
        "w": 1920,
        "h": 1080,
        "api": [],
        "skip": 0
      }
    }
  ],
  "device": {
    "ua": "Mozilla/5.0 (Linux; Android 12; Android TV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "ip": "198.51.100.24",
    "devicetype": 3,
    "os": "Android TV",
    "osv": "12",
    "lmt": 1,
    "geo": {
      "country": "USA",
      "type": 2
    }
  },
  "source": {
    "fd": 1,
    "tid": "326fe34d-d1da-46a1-9372-3d396e3c6002"
  },
  "regs": {
    "coppa": 0
  }
}
Android phone · complete request

devicetype: 4 identifies a phone; use 5 for a tablet. The video dimensions describe the player, not the physical screen. Advertising identifiers are optional and subject to the privacy policy in §4.

{
  "id": "sandbox-android-phone-001",
  "test": 1,
  "at": 1,
  "cur": [
    "USD"
  ],
  "tmax": 500,
  "app": {
    "id": "sample-android-mobile",
    "name": "Example Mobile",
    "bundle": "com.example.mobile",
    "storeurl": "https://play.google.com/store/apps/details?id=com.example.mobile",
    "publisher": {
      "id": "publisher-001",
      "name": "Example Media",
      "domain": "example.com"
    },
    "content": {
      "id": "sample-episode-001",
      "title": "Sample Documentary",
      "series": "Example Series",
      "season": "1",
      "episode": 1,
      "genre": "Documentary",
      "livestream": 0,
      "len": 1800,
      "language": "en",
      "contentrating": "TV-PG"
    }
  },
  "imp": [
    {
      "id": "1",
      "tagid": "sample-mobile-preroll",
      "secure": 1,
      "bidfloor": 1.0,
      "bidfloorcur": "USD",
      "video": {
        "mimes": [
          "video/mp4"
        ],
        "protocols": [
          2,
          3,
          5,
          6,
          7,
          8
        ],
        "plcmt": 1,
        "linearity": 1,
        "startdelay": 0,
        "minduration": 6,
        "maxduration": 30,
        "w": 640,
        "h": 360,
        "api": [],
        "skip": 0
      }
    }
  ],
  "device": {
    "ua": "Mozilla/5.0 (Linux; Android 14; SM-S911B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36",
    "ip": "198.51.100.24",
    "devicetype": 4,
    "make": "Samsung",
    "model": "SM-S911B",
    "os": "Android",
    "osv": "14",
    "lmt": 1,
    "geo": {
      "country": "USA",
      "type": 2
    }
  },
  "source": {
    "fd": 1,
    "tid": "326fe34d-d1da-46a1-9372-3d396e3c6003"
  },
  "regs": {
    "coppa": 0
  }
}
Web video · complete request

Use site for browser inventory, including mobile web. This sample is desktop instream video; use the actual device and placement classification for your traffic. The US fixture contains no TCF or GPP payload. Supply the real applicable signals for any live request.

{
  "id": "sandbox-web-video-001",
  "test": 1,
  "at": 1,
  "cur": [
    "USD"
  ],
  "tmax": 500,
  "imp": [
    {
      "id": "1",
      "tagid": "sample-web-instream",
      "secure": 1,
      "bidfloor": 1.0,
      "bidfloorcur": "USD",
      "video": {
        "mimes": [
          "video/mp4"
        ],
        "protocols": [
          2,
          3,
          5,
          6,
          7,
          8
        ],
        "plcmt": 1,
        "linearity": 1,
        "startdelay": 0,
        "minduration": 6,
        "maxduration": 30,
        "w": 640,
        "h": 360,
        "api": [],
        "skip": 0
      }
    }
  ],
  "device": {
    "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "ip": "198.51.100.24",
    "devicetype": 2,
    "os": "Windows",
    "geo": {
      "country": "USA",
      "type": 2
    }
  },
  "source": {
    "fd": 1,
    "tid": "326fe34d-d1da-46a1-9372-3d396e3c6004"
  },
  "regs": {
    "coppa": 0
  },
  "site": {
    "id": "sample-web",
    "name": "Example Video",
    "domain": "video.example.com",
    "page": "https://video.example.com/watch/sample-episode",
    "publisher": {
      "id": "publisher-001",
      "name": "Example Media",
      "domain": "example.com"
    },
    "content": {
      "id": "sample-episode-001",
      "title": "Sample Documentary",
      "series": "Example Series",
      "season": "1",
      "episode": 1,
      "genre": "Documentary",
      "livestream": 0,
      "len": 1800,
      "language": "en",
      "contentrating": "TV-PG"
    }
  }
}

What changes per channel

FieldCTVMobile in-appWeb
Inventory objectappappsite
Device types3 TV; 7 STB; 6 only for verified connected-device inventory4 phone; 5 tablet; 1 general mobile/tabletUse the real device: commonly 2, 4 or 5
AuthorisationRegistered app + store/platformRegistered app + store/platformRegistered site.domain
Store listingRequired for the standard live CTV profile; exceptions must be agreedSupply the official listing; requirements agreed per platformNot applicable
ContentTruthful programme metadata for content video; exact fields agreedWhere relevant and availablesite.content where relevant
Advertising IDWhen available and permitted; never fabricatedWhen available and permitted; never fabricatedNo universal advertising-ID requirement
Banner / videoVideoBanner and video, on enabled platformsBanner and video
PrivacyApplicable market and user signalsApplicable market and user signalsApplicable market and user signals

The bid you receive

The following is the standard markup profile. adm contains VAST XML; the wrapper points to the managed creative. This profile must be enabled and tested for the connection. Existing URL-profile integrations use the compatibility example in §7.

{
  "id": "sandbox-roku-001",
  "seatbid": [
    {
      "seat": "adcrew",
      "bid": [
        {
          "id": "adcrew-sandbox-1",
          "impid": "1",
          "price": 1.25,
          "adm": "<VAST version=\"4.0\"><Ad id=\"sample-ad\"><Wrapper><AdSystem version=\"1.0\">AdCrew</AdSystem><VASTAdTagURI><![CDATA[https://vast.adcrew.co/vast/SANDBOX_CREATIVE_TOKEN]]></VASTAdTagURI><Impression><![CDATA[https://vast.adcrew.co/evt/SANDBOX_CREATIVE_TOKEN/imp]]></Impression><Creatives><Creative><Linear><TrackingEvents><Tracking event=\"start\"><![CDATA[https://vast.adcrew.co/evt/SANDBOX_CREATIVE_TOKEN/start]]></Tracking></TrackingEvents></Linear></Creative></Creatives></Wrapper></Ad></VAST>",
          "adomain": [
            "advertiser.example"
          ],
          "crid": "sandbox-creative-001",
          "mtype": 2,
          "protocol": 8,
          "dur": 30,
          "exp": 300
        }
      ]
    }
  ],
  "cur": "USD"
}

price is USD CPM, net payable to you for valid billable impressions. Do not deduct AdCrew’s margin again. exp: 300 is an illustrative five-minute impression deadline, not a guarantee that every connection has a five-minute creative-cache lifetime. No bid uses 204 with an empty body.

2Authentication

Your credential is issued in one of two modes. A key issued for one mode is not accepted in the other. Both modes use HTTPS and account authorisation.

CapabilitySigned headersURL token
Choose it whenYou control the calling service and can sign each requestYour server platform accepts an endpoint URL but cannot add a signature
CredentialKey ID and HMAC secretBearer token in the issued URL
Request authenticationFour signed headersToken validated on each request
Body integrity in authenticationHMAC covers the body hashNo body signature; HTTPS protects transport
Replay protectionUnique nonce and timestamp validationNo nonce-based replay protection
Pinned to your IPsOptionalOptional

IP pinning is optional in both authentication modes. Choose whether to enable it on the connection sheet. An integration does not require a fixed egress IP when pinning is disabled. If enabled, send the agreed egress IPs or CIDR ranges; requests outside that list receive the generic 401. A key with pinning enabled must not be activated with an empty allowlist.

IP pinning checks the caller’s network egress, as established by the trusted edge configuration. It does not use the viewer address in device.ip or device.ipv6. Changing viewer locations must not break authentication. Key validation, inventory permissions and limits still apply when pinning is disabled.

URL token

Use the exact endpoint issued for your environment. The production path form is:

POST https://exchange.adcrew.co/rtb/v1/auction/adx_<token>
Content-Type: application/json
X-OpenRTB-Version: 2.6
User-Agent: YourSSP-RTB/1.4

The alternative /rtb/v1/auction?token=adx_<token> form is for connections explicitly issued that format. Treat the entire URL as a credential. Redact tokens from access logs, analytics, traces, tickets and screenshots in both path and query forms.

  • Optional pinning: supply an egress list only when you choose to enable it.
  • Rotation: issue a second credential, switch the caller, then revoke the first. Two credentials may overlap during the agreed transition.
  • Storage: keep the URL in server-side secret configuration. Never embed it in a public app or page.

After saving a sandbox JSON example as request.json, the following sends its exact file bytes. Populate ADCREW_SANDBOX_URL from the issued connection sheet; it must be the isolated sandbox token URL.

curl --request POST --proto '=https' \
  "$ADCREW_SANDBOX_URL" \
  --header 'Content-Type: application/json' \
  --header 'X-OpenRTB-Version: 2.6' \
  --user-agent 'YourSSP-RTB/1.4' \
  --data-binary @request.json \
  --max-time 2

Signed headers

HeaderValue
X-AdCrew-KeyIssued key ID
X-AdCrew-TimestampMilliseconds since Unix epoch
X-AdCrew-NonceUnique per request; ASCII alphanumeric only; 16–64 characters
X-AdCrew-SignatureLowercase hexadecimal HMAC-SHA256

The signed message has seven newline-separated fields and no trailing newline. Use the canonical signing path supplied for the environment. The production path is /rtb/v1/auction.

v1
POST
<canonical signing path>
<key id>
<timestamp in milliseconds>
<nonce>
<lowercase SHA-256 hex of raw body bytes>

Serialise once, hash the exact bytes, and send those same bytes. The secret is used as issued, encoded as UTF-8; do not apply an extra base64 or hexadecimal decode unless the credential instructions explicitly require it. The example below uses Python’s standard library and an issued sandbox key.

import hashlib
import hmac
import json
import os
import secrets
import time
from pathlib import Path
from urllib.error import HTTPError
from urllib.parse import urlsplit
from urllib.request import Request, urlopen


def sign(key_id, secret, body, signing_path):
    timestamp = str(time.time_ns() // 1_000_000)
    nonce = secrets.token_hex(16)
    body_hash = hashlib.sha256(body).hexdigest()
    message = "\n".join([
        "v1", "POST", signing_path, key_id,
        timestamp, nonce, body_hash,
    ]).encode("utf-8")
    signature = hmac.new(
        secret.encode("utf-8"), message, hashlib.sha256
    ).hexdigest()
    return {
        "X-AdCrew-Key": key_id,
        "X-AdCrew-Timestamp": timestamp,
        "X-AdCrew-Nonce": nonce,
        "X-AdCrew-Signature": signature,
    }


# All three values are issued privately for the sandbox.
endpoint = os.environ["ADCREW_SANDBOX_URL"]
key_id = os.environ["ADCREW_KEY_ID"]
secret = os.environ["ADCREW_HMAC_SECRET"]
parsed = urlsplit(endpoint)
if parsed.scheme != "https" or not parsed.netloc:
    raise SystemExit("An issued HTTPS sandbox endpoint is required")
if parsed.query or parsed.fragment:
    raise SystemExit("Use the issued signed-header URL without a query")
signing_path = os.environ.get("ADCREW_SIGNING_PATH", parsed.path)

payload = json.loads(Path("request.json").read_text(encoding="utf-8"))
if payload.get("test") != 1:
    raise SystemExit("This example sends sandbox test requests only")
body = json.dumps(payload, separators=(",", ":")).encode("utf-8")
headers = sign(key_id, secret, body, signing_path)
headers.update({
    "Content-Type": "application/json",
    "X-OpenRTB-Version": "2.6",
    "User-Agent": "YourSSP-RTB/1.4",
})
request = Request(endpoint, data=body, headers=headers, method="POST")
try:
    with urlopen(request, timeout=2) as response:
        print(response.status)
        print(response.read().decode("utf-8"))
except HTTPError as response:
    print(response.code)
    print(response.read().decode("utf-8", errors="replace"))

This diagnostic client prints a response and never serves an ad. In a serving integration, enforce the auction deadline independently of the transport timeout and discard late bids. Do not add automatic retries for an expired auction.

  • Timestamp tolerance is ±90 seconds; keep clocks synchronised.
  • A UUID containing dashes is not a valid nonce. uuid4().hex and secrets.token_hex(16) are valid formats.
  • A nonce must remain blocked for the entire period in which its signed timestamp could still be accepted, including future clock skew. AdCrew must enforce replay checks across all serving instances.
Offline HMAC reference vector

Use this fixed vector to compare implementations across languages. Its timestamp is intentionally expired, its secret is public, and its body is not a valid auction. Do not send it to an endpoint.

{
  "purpose": "offline signature verification only; not an auction request",
  "key_id": "example-key",
  "secret_utf8": "example-secret-do-not-use",
  "timestamp_ms": "1700000000000",
  "nonce": "0123456789abcdef0123456789abcdef",
  "body_utf8": "{}",
  "body_sha256": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
  "canonical_message_utf8": "v1\nPOST\n/rtb/v1/auction\nexample-key\n1700000000000\n0123456789abcdef0123456789abcdef\n44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
  "expected_signature_hex": "244f805cfcd062457fcd27321239b836a6297b9d9bed2dca3af7b9b87985020f"
}

Authentication failures

Unknown or expired keys, invalid signatures, reused nonces, disabled accounts and an IP mismatch when pinning is enabled return the same 401 status and generic body. Diagnostic references must not disclose the failure reason or credentials.

Provide the request ID if available, exact UTC timestamp with milliseconds, environment, authentication mode and any returned trace or edge reference. AdCrew investigates the detailed reason internally. Never send a secret, full token URL or authentication headers in a support ticket.

3Response codes

The rules below distinguish invalid requests from valid opportunities that do not receive a bid. Error-body fields are an AdCrew extension; no-bid diagnostics use the extension in §7.

HTTPMeaningCaller action
200At least one bid. JSON OpenRTB response; each bid references an offered impid.Validate the bid, deadline and profile; serve it only if selected.
204No bid for any eligible impression. Empty body.Continue normal ad decisioning. Monitor aggregate no-bid changes.
400Invalid JSON, required-field failure, malformed impression or Schain, invalid privacy input, unsupported currency, or test traffic on the production endpoint.Fix the request or environment. Do not retry unchanged.
401Generic authentication failure, including an IP mismatch only if pinning is enabled.Use the support reference fields in §2.
403Account is not authorised for the submitted inventory, device class or market.Correct inventory or agree an authorisation change.
413Request exceeds the configured body-size limit; baseline 262,144 bytes.Reduce the body and stay within the connection limit.
429QPS, burst or concurrency limit exceeded; Retry-After indicates when to reduce/restart future traffic.Throttle future requests; do not replay an expired impression.
5xxAdCrew or edge service failure.Record the error, reduce traffic if persistent and contact operations.

Multi-impression requests

  • Malformed request or impression: reject the whole request with 400; there are no usable bids in that response. A detail array may identify the failing impression.
  • Well-formed but unsupported or ineligible impression: decline that impression and evaluate other valid impressions. Return 200 if any wins are offered; include ext.seatnonbid when enabled.
  • No bids remain: return 204 with no JSON body. Reasons are available through agreed diagnostics or reporting. This profile does not put nbr inside a 204 response.

A downstream demand timeout or failure can result in a supplier-facing 204. Internally, demand errors, latency exhaustion, policy rejection and ordinary no-bid must remain distinguishable. An individual 204 is normal; a material change in its rate can still merit investigation.

Error-body example

{
  "error": "Invalid country code",
  "field": "device.geo.country",
  "request_id": "example-request-001"
}

Non-authentication error responses may include field, request_id and impression details. Do not depend on English error text as a stable machine code. Edge errors may have a different format; the HTTP status remains authoritative.

4The request

This guide defines AdCrew’s supported subset and partner-specific requirements on top of OpenRTB 2.6. The connection sheet records the exact deployed build and dated specification revision. It does not imply support for every optional OpenRTB feature.

InputAdCrew contract
idUnique auction/request ID, 1–64 characters. Response id echoes it.
imp[]At least one impression, with unique non-empty impression IDs. For supported traffic, exactly one of video or banner per impression. Multi-format impressions are outside this v1 profile.
app or siteExactly one, describing the authorised property. Native/audio-only opportunities are unsupported media, handled as in §3.
deviceTruthful devicetype and ua or supported sua. The standard live profile requires permitted client network data; masked/no-IP and IPv6-only paths must be explicitly validated.
Client addressdevice.ip is IPv4; device.ipv6 is IPv6. Never substitute your server’s address or invent a client IP.
device.geo.countryRequired for this profile; ISO-3166-1 alpha-3 such as USA, EGY or SAU. Missing/invalid country returns 400; it must not silently remove a floor.
source.tidUnique transaction ID for the auction. Preserve an existing valid upstream transaction ID for the same transaction; do not reuse one constant across auctions.
source.schainRequired for intermediary supply. An approved direct owned-and-operated account may omit the incoming chain; see §6.
tmaxPositive maximum bid-response time in milliseconds, including network latency.
cur / bidfloorcurThis profile transacts in USD. Send cur:["USD"] and USD floors.
test1 for the isolated sandbox. Production accepts 0 or an omitted flag only after live activation; a production request with 1 must be rejected. Never coerce test traffic into live traffic.

Private, loopback, link-local and reserved documentation addresses are invalid for standard live requests. The isolated sandbox may allow only its agreed fixture ranges. If privacy restrictions prevent a required signal, use an explicitly supported restricted-data path or receive no eligible demand; never fabricate or reconstruct it.

ext.prebid does not configure bidders on this supplier endpoint. AdCrew owns demand routing. This guide does not document a Prebid.js adapter or direct public access to Prebid Server.

Video capabilities and placement

Send mimes and protocols, dimensions, placement, linearity, start delay and acceptable durations. Declare only the formats and APIs the player or SSAI chain actually supports. The examples use MP4, VAST 2/3/4 and no VPAID; they are not a mandate to claim capabilities your player lacks.

ValueMeaning / rule
plcmt:1Instream: advertising around requested video content, with the viewing intent and playback behaviour required by the IAB definition. Content metadata alone does not make a placement instream.
plcmt:2Accompanying content: video accompanying other primary page content, following the IAB playback and viewport rules.
plcmt:3Interstitial video.
plcmt:4Standalone video without streaming content.
api:[2]VPAID 2.0; not supported on CTV in this profile. Do not include it in a CTV request.
protocols:[2,3,5,6]VAST 2.0/3.0 and their wrappers. Values 7/8 add VAST 4.0/its wrapper only when supported.

Newer placement types or protocol revisions require explicit enablement. For web banners, do not copy mobile MRAID API declarations unless the rendering environment supports them.

Compatibility without changing meaning

Use plcmt on this endpoint. A legacy placement value is not a numeric synonym: for example, legacy placement:2 means in-banner, while plcmt:2 means accompanying content. Any downstream conversion needs an explicit, tested mapping based on actual context. Where no faithful mapping exists, use a compatible route or decline the opportunity.

rqddurs lists exact acceptable durations. Use it instead of minduration/maxduration in a 2.6 video object. For example, [15,30] allows 15 or 30 seconds, not every duration between them. A legacy downstream range may be used only with final validation against the original exact set; never accept a 20-second ad for that request.

Floors, currency and net pricing

imp.bidfloor is the minimum acceptable net USD CPM for that impression. Omitted or zero means no positive minimum supplied in that field; it does not set the final auction price to zero. A separately agreed account floor may still apply.

The effective supplier floor must respect both the supplied minimum and any applicable configured minimum. Missing enrichment must never erase a supplied floor. After fees and rounding, AdCrew must not return a supplier-net bid below that effective minimum. Send the supplier-net floor; do not gross it up for AdCrew’s margin.

Non-USD request or floor currencies receive 400 in this profile. Non-USD downstream bids are ineligible. No currency conversion is promised.

Display · complete web example

Use format for accepted sizes and validate the returned creative dimensions. A page offering separate video and banner slots uses separate impression IDs. See §7 for HTML rendering.

Web banner · request JSON
{
  "id": "sandbox-web-banner-001",
  "test": 1,
  "at": 1,
  "cur": [
    "USD"
  ],
  "tmax": 500,
  "imp": [
    {
      "id": "b1",
      "tagid": "sample-web-banner",
      "secure": 1,
      "bidfloor": 0.25,
      "bidfloorcur": "USD",
      "banner": {
        "format": [
          {
            "w": 300,
            "h": 250
          },
          {
            "w": 336,
            "h": 280
          }
        ],
        "w": 300,
        "h": 250,
        "api": []
      }
    }
  ],
  "device": {
    "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "ip": "198.51.100.24",
    "devicetype": 2,
    "os": "Windows",
    "geo": {
      "country": "USA",
      "type": 2
    }
  },
  "source": {
    "fd": 1,
    "tid": "326fe34d-d1da-46a1-9372-3d396e3c6005"
  },
  "regs": {
    "coppa": 0
  },
  "site": {
    "id": "sample-web",
    "name": "Example Video",
    "domain": "video.example.com",
    "page": "https://video.example.com/watch/sample-episode",
    "publisher": {
      "id": "publisher-001",
      "name": "Example Media",
      "domain": "example.com"
    },
    "content": {
      "id": "sample-episode-001",
      "title": "Sample Documentary",
      "series": "Example Series",
      "season": "1",
      "episode": 1,
      "genre": "Documentary",
      "livestream": 0,
      "len": 1800,
      "language": "en",
      "contentrating": "TV-PG"
    }
  }
}

Privacy signals

Apply the relevant market and user signals to CTV, in-app and web. Signal presence is not proof of permission. The connection must document which signals are parsed, which decisions are enforced, what data is removed and which downstream routes remain eligible.

Signal / caseRequired handling
regs.gdpr; legacy regs.ext.gdprAccept the canonical field; legacy handling must be mapped consistently. In this profile, GDPR-scoped traffic requires a valid TCF input through an enabled path. Missing, malformed or contradictory required inputs receive 400.
user.consent; legacy user.ext.consentTCF input must be decoded and evaluated for the relevant recipients and purposes. A valid signal that denies permission is handled by restricting processing/routing, not by inventing consent.
regs.gpp and regs.gpp_sidPass the original GPP payload and applicable section IDs. Section 2 represents EU TCF. A GPP-only EU input is usable only after that parsing path is verified. Until then, require a consistent user.consent copy or reject the unsupported input; do not silently ignore the section.
US national/state GPP sectionsPreserve the signals and apply the configured restrictions to collection, processing and downstream eligibility. Forwarding alone is not an enforcement guarantee.
regs.coppa:1For this conservative profile, remove advertising IDs, hashed device identifiers, user IDs, buyer IDs and EIDs; remove precise or granular location, including lat/lon, zip and metro, before downstream transmission. Apply any additional account restrictions.
device.lmt:1 or device.dnt:1Apply the same identifier and granular-location minimisation policy. Retain coarse signals only where permitted. Never replace a removed identifier with a derived substitute.
No available/permitted IFAOmit the IFA. Use eligible non-identifier demand only if enabled; otherwise no bid. Do not fail authentication, invent an ID or label the device fraudulent solely because an IFA is absent.
Legacy US privacy stringSupport and precedence must be recorded in the connection sheet. Preserve applicable signals; do not treat a legacy string as a substitute for missing required GPP sections.
Conflicting or unknown inputsDo not downgrade restrictions. Reject invalid required input or use a documented restrictive path; do not silently overwrite the signal.

For iOS or other platform-specific privacy frameworks, enable the integration only after platform ID formats, permission handling and applicable measurement requirements are agreed and tested. This Android-focused example set does not certify iOS readiness.

Timeouts

tmax is the supplier’s total deadline. AdCrew must reserve time for processing and the return path, and finish before that deadline. Insufficient remaining time yields no bid. The previous guide’s approximate 180 ms cut-off is not a universal OpenRTB limit; actual admission thresholds belong on the connection sheet.

The examples use 500 ms. A 300–500 ms CTV pilot budget is a starting point to validate against geography, measured latency and supplier requirements, not a guaranteed SLA. AdCrew makes at most one attempt per selected downstream demand endpoint during the auction, without in-auction retries.

5Inventory authorisation

Agree inventory permissions before sending traffic. Application-level authorisation is separate from optional network IP pinning. A property, device or market outside the agreed account permissions receives 403.

FieldRule
app.bundleExact registered identifier, case-sensitive under this profile, paired with the correct platform/store. Roku, Android and iOS identifiers are not interchangeable.
site.domainRegistered hostname, compared case-insensitively. Define wildcard scope explicitly; register the apex separately when needed. Do not use substring matching.
device.devicetypeCorrect device enumeration and agreed channel mapping. Type 6 is connected device, not an automatic label for all OTT traffic.
device.geo.countryValid alpha-3 code; market must be on the agreed list. Invalid/missing syntax is 400; valid but unauthorised market is 403.
MediaCTV video; web/in-app banner or video on the enabled platform. Valid unsupported formats are declined as described in §3.

Signals that affect CTV eligibility

SignalWhat it enables
Store URL, app ID and app nameResolve the actual app and its developer. Keep platform, store listing and identifier consistent.
Publisher identityConnect the inventory to the legal seller and contract. publisher.id is an integration identifier, not necessarily a public store-listing ID.
Content metadataContent targeting and suitability checks: truthful title, genre, live/VOD flag, language, rating, network/channel and programme identifiers where available.
Device make, model and OSDevice targeting and consistency checks. Populate only accurate values.
Advertising ID and limit flagsPermitted frequency/measurement use where supported. Identifier absence changes eligibility; no universal fill percentage is implied.
Placement, durations and SSAIDescribe the actual viewing context, slot constraints and insertion/tracking arrangement. Declare imp.ssai when supported and accurate.

AdCrew may validate and normalise supported representations, but it must not fabricate missing programme identity, store identity, user permission or device identifiers. Privacy filtering takes precedence over ordinary passthrough.

Finding app-ads.txt

  1. Start with the official app listing identified by app.storeurl.
  2. Read the developer website published in that store listing.
  3. Derive and fetch /app-ads.txt using the app-ads.txt domain rules.
  4. Verify the relevant advertising-system and seller-ID records against the actual selling path.

The file is hosted on the developer website domain discovered from the listing; do not assume it lives on the app store’s own domain. For web inventory, verify the publisher’s ads.txt using the corresponding web rules.

The standard live CTV profile requires verifiable app identity and selling authorisation. If the listing is unavailable, the app is unpublished or a store requires a special verification method, keep testing in the sandbox until an explicit live eligibility decision is recorded. Demand-specific requirements vary; no universal “zero fill” or guaranteed monetisation claim is made.

Inventory quality and creative controls

Document the enabled source validation, duplicate-traffic checks, IVT decisions, publisher blocklists and creative controls in the partner acceptance record. Preserve genuine buyer adomain, category and creative identifiers, and validate applicable restrictions before returning a bid. Specific measurement vendors, certifications and performance guarantees must be named only when actually available and contracted.

6Supply chain

source.schain describes the advertising systems and seller accounts in the payment path. Use the actual chain; never add a decorative publisher node or hide an intermediary to meet a buyer’s limit.

  • Intermediary supply: provide a valid incoming chain, including your own selling-system node. A missing/malformed required chain receives 400.
  • Allowed upstream ASI: the last incoming node’s asi must match an upstream advertising system agreed with AdCrew. This check does not, by itself, prove all earlier nodes are authorised.
  • AdCrew node: append asi: "adcrew.co", your seller ID in AdCrew and hp:1. Do not truncate or reorder the received chain.
  • Completeness: preserve an incomplete chain as complete:0. A complete chain is eligible only when the actual path and authorisation checks support that declaration; allowlisting must not promote an incomplete chain to complete.
  • Direct owned-and-operated: an approved publisher/OEM account with no prior selling-system payment hop may omit the incoming chain. AdCrew then originates a one-node complete chain after verifying the direct relationship.

Count the actual selling-system nodes

Illustrative path to demandNodes after AdCrewEligibility for a route capped at 2
Publisher → AdCrew → buyer1Eligible on chain length, subject to other checks
Publisher → SSP → AdCrew → buyer2Eligible on chain length, subject to other checks
Publisher → SSP → another reseller → AdCrew → buyer3Ineligible for that route

These examples assume no additional selling systems. A publisher/OEM may itself operate a selling system; count its real role rather than infer the count from ownership alone. The earlier guide described CTV demand routes capped at two nodes. Confirm each active route’s current cap during onboarding. That is a demand-route restriction, not a universal OpenRTB rule.

Outgoing chain examples · direct and intermediary

These objects illustrate the chain after AdCrew has processed it. Seller IDs and the example SSP domain are placeholders. They are not incoming request templates.

{
  "source": {
    "schain": {
      "ver": "1.0",
      "complete": 1,
      "nodes": [
        {
          "asi": "adcrew.co",
          "sid": "publisher-001",
          "hp": 1
        }
      ]
    }
  }
}
{
  "source": {
    "schain": {
      "ver": "1.0",
      "complete": 1,
      "nodes": [
        {
          "asi": "ssp.example.com",
          "sid": "publisher-001",
          "hp": 1
        },
        {
          "asi": "adcrew.co",
          "sid": "ssp-001",
          "hp": 1
        }
      ]
    }
  }
}

Seller records and authorisation

The sid in the AdCrew node identifies the entity AdCrew pays. It must resolve to the correct seller record in adcrew.co/sellers.json. A seller representing owned inventory is classified PUBLISHER; a reseller is INTERMEDIARY; use BOTH only when both roles genuinely apply.

Account relationshipIllustrative publisher authorisation
Publisher directly controls its AdCrew accountadcrew.co, publisher-001, DIRECT
Publisher authorises an intermediary controlling its AdCrew accountadcrew.co, ssp-001, RESELLER

Use issued seller IDs, the actual account-control relationship and any valid optional certification identifier. Publish any other records required for the genuine supply path. A direct publisher does not need to invent an advertising-system sellers.json solely to create an extra node. Each participating advertising system is responsible for its own applicable seller disclosures.

7The response, and how to serve it

AdCrew returns bids under seat: "adcrew", with USD CPM prices net to the supplier. The enabled creative representation must be written on the connection sheet and verified in the sandbox.

Response profileVideo admBanner adm
Standard markup · target profileVAST XML, inline or an agreed wrapper. The XML may point to the managed AdCrew creative URL.HTML markup for the agreed rendering environment, including required impression tracking.
URL compatibility · explicitly agreedA bare managed VAST URL, only for partners that explicitly support this representation.A managed HTML URL, only for partners that explicitly support fetching and rendering it.
URL compatibility · response example

This is an AdCrew-specific representation, not the standard markup profile. Do not auto-detect it by guessing from the content of adm; use the connection’s agreed profile.

{
  "id": "sandbox-roku-001",
  "seatbid": [
    {
      "seat": "adcrew",
      "bid": [
        {
          "id": "adcrew-sandbox-1",
          "impid": "1",
          "price": 1.25,
          "adm": "https://vast.adcrew.co/vast/SANDBOX_CREATIVE_TOKEN",
          "adomain": [
            "advertiser.example"
          ],
          "crid": "sandbox-creative-001",
          "mtype": 2,
          "dur": 30,
          "exp": 300
        }
      ]
    }
  ],
  "cur": "USD"
}
Standard banner markup · response example

The creative image, click destination and impression token are illustrative. A runnable sandbox must return its own test assets. The selected size must be one of the sizes offered in the request.

{
  "id": "sandbox-web-banner-001",
  "seatbid": [
    {
      "seat": "adcrew",
      "bid": [
        {
          "id": "adcrew-sandbox-banner-1",
          "impid": "b1",
          "price": 0.5,
          "adm": "<a href=\"https://advertiser.example/\"><img src=\"https://creative.example/banner-300x250.png\" width=\"300\" height=\"250\" alt=\"Advertisement\"></a><img src=\"https://vast.adcrew.co/evt/SANDBOX_BANNER_TOKEN/imp\" width=\"1\" height=\"1\" alt=\"\">",
          "adomain": [
            "advertiser.example"
          ],
          "crid": "sandbox-banner-001",
          "mtype": 1,
          "w": 300,
          "h": 250,
          "exp": 300
        }
      ]
    }
  ],
  "cur": "USD"
}

Response validation and rendering

  • Match response id to the request and impid to a real offered impression. Validate currency, net floor, expiry, dimensions and duration before selection.
  • Use mtype when supplied: 1 banner, 2 video. If absent, derive the type from the uniquely matched single-format request impression. Do not determine media type from a URL path.
  • For standard video markup, hand the VAST XML to the supported player/SSAI integration. For the URL profile, fetch the issued URL only at the agreed selection point and honour the returned Content-Type.
  • Render banner markup in the approved isolated ad container or SDK renderer. Preserve the supplied tracking. Do not inject arbitrary buyer HTML into the publisher’s top-level application DOM.
  • Preserve actual buyer adomain, cat, crid and applicable taxonomy/creative attributes. Do not substitute AdCrew’s own domain for the advertiser.

Optional fields are omitted when unavailable, not set to null. Forward or derive fields only when their meaning is known. dur must be available and validated for exact-duration pod bids. For display, provide the selected size where required. Support for dealid, newer apis, taxonomy revisions, language fields or other optional attributes must be recorded in the feature matrix; this guide does not promise arbitrary passthrough.

Partial no-bid diagnostics

When enabled, a response containing bids may also describe declined impressions through the IAB ext.seatnonbid extension. Use statuscode, not status.

{
  "ext": {
    "seatnonbid": [
      {
        "seat": "adcrew",
        "nonbid": [
          {
            "impid": "slot-2",
            "statuscode": 202,
            "ext": {
              "reason": "Unsupported media type for this connection"
            }
          }
        ]
      }
    ]
  }
}
Status codeMeaning
0General no bid
15Insufficient auction time
101Demand timeout
202Request blocked: unsupported media type
204Request blocked: privacy
301Response rejected: below floor
302Response rejected: duplicate

The extension must reference an impression present in the associated request. A diagnostic statuscode:204 is unrelated to HTTP 204. Unsupported dynamic pods may use a documented vendor code of 500+ when diagnostics are enabled. If there are no bids, return HTTP 204 with an empty body and retain the reason internally.

Structured pods

Use one impression per predetermined slot and the same video.podid for slots in the same break. The example below offers two mid-roll slots of exactly 15 and 30 seconds. It uses no dynamic-pod fields.

Structured pod · complete request
{
  "id": "sandbox-structured-pod-001",
  "test": 1,
  "at": 1,
  "cur": [
    "USD"
  ],
  "tmax": 500,
  "app": {
    "id": "sample-roku-channel",
    "name": "Example Channel",
    "bundle": "123456",
    "storeurl": "https://channelstore.roku.com/details/123456/example-channel",
    "publisher": {
      "id": "publisher-001",
      "name": "Example Media",
      "domain": "example.com"
    },
    "content": {
      "id": "sample-episode-001",
      "title": "Sample Documentary",
      "series": "Example Series",
      "season": "1",
      "episode": 1,
      "genre": "Documentary",
      "livestream": 0,
      "len": 1800,
      "language": "en",
      "contentrating": "TV-PG"
    }
  },
  "imp": [
    {
      "id": "slot-1",
      "tagid": "sample-pod-slot-1",
      "secure": 1,
      "bidfloor": 1.0,
      "bidfloorcur": "USD",
      "video": {
        "mimes": [
          "video/mp4"
        ],
        "protocols": [
          2,
          3,
          5,
          6,
          7,
          8
        ],
        "plcmt": 1,
        "linearity": 1,
        "startdelay": -1,
        "w": 1920,
        "h": 1080,
        "api": [],
        "skip": 0,
        "rqddurs": [
          15
        ],
        "podid": "sample-pod-1",
        "podseq": 1
      }
    },
    {
      "id": "slot-2",
      "tagid": "sample-pod-slot-2",
      "secure": 1,
      "bidfloor": 1.0,
      "bidfloorcur": "USD",
      "video": {
        "mimes": [
          "video/mp4"
        ],
        "protocols": [
          2,
          3,
          5,
          6,
          7,
          8
        ],
        "plcmt": 1,
        "linearity": 1,
        "startdelay": -1,
        "w": 1920,
        "h": 1080,
        "api": [],
        "skip": 0,
        "rqddurs": [
          30
        ],
        "podid": "sample-pod-1",
        "podseq": 1
      }
    }
  ],
  "device": {
    "ua": "Roku/DVP-12.0 (12.0.0.4182-45)",
    "ip": "198.51.100.24",
    "devicetype": 3,
    "os": "Roku OS",
    "osv": "12.0",
    "lmt": 1,
    "geo": {
      "country": "USA",
      "type": 2
    }
  },
  "source": {
    "fd": 1,
    "tid": "326fe34d-d1da-46a1-9372-3d396e3c6006"
  },
  "regs": {
    "coppa": 0
  }
}

Validate each returned duration and match every bid to its slot. The supplier constructs the final pod. AdCrew’s selected winners within a pod must respect the agreed advertiser-domain deduplication rule. That does not by itself guarantee category-level competitive separation, session frequency capping, or deduplication against winners from other exchanges. Agree responsibility for those controls separately.

Wins, serving and billable impressions

EventMeaning
Bid responseAn offer, not a win and not a billable impression.
Supplier selection / winThe supplier selects AdCrew’s bid. In the fetch-as-win profile, the first production creative fetch records that selection; the supplier must therefore fetch only after selection.
VAST/HTML retrievalCreative resolution. It does not alone establish a billable impression. Prefetch before selection is not enabled in the fetch-as-win profile.
Video impression trackerA valid VAST impression event is the agreed video billing trigger, subject to validity checks and contractual reconciliation.
Banner impression trackerThe renderer triggers the supplied impression pixel at the agreed rendering point. The trigger and counting policy must be tested; mere HTML retrieval does not bill.
Playback and error eventsStart, quartiles, complete, click and errors provide measurement. They must not create additional billable impressions.

AdCrew manages its downstream buyer nurl/burl and applicable macro substitution. Suppliers must not call private downstream notices. If a supplier-facing notice URL is explicitly included in the enabled response profile, follow that profile’s documented trigger. No unsupported prefetch or win-notice mechanism should be assumed.

In the managed path, a valid /evt/<token>/imp event is associated with the accepted bid and impression. VAST errors and playback tracking must use the supplied URLs and macros. Do not manufacture production events for QA.

Expiry and duplicate events

bid.exp is the bidder’s maximum advisory wait from auction to actual impression. The connection sheet separately defines creative retrieval lifetime, the last accepted event time and handling of late events. The effective serving window must not exceed an upstream buyer’s limit. Do not reuse one creative token for a different impression or device.

Repeated resolution or duplicate delivery of the same event must not create extra wins or billable impressions. AdCrew must validate event identity and deduplicate across all serving instances and restarts within the agreed window. Behaviour after creative expiry, including HTTP status, must be recorded and tested.

Pricing and reconciliation

For one valid billable impression, supplier payable USD = net CPM ÷ 1,000. At $1.25 net CPM, one impression is $0.00125 and one million valid impressions total $1,250.

If money is recorded in integer microdollars, the per-impression amount is net CPM × 1,000, using an agreed precision and rounding policy. Do not record CPM × 1,000,000 as the payable for a single impression.

Reconcile by UTC date, partner, app/domain, media type and currency, with request/bid/impression references for sampled disputes. Record report source, discrepancy calculation and threshold, retention, settlement schedule, permitted adjustments and dispute process in the commercial schedule. Do not promise a universal discrepancy tolerance or payment term.

8Limits

Limits are agreed per connection and must be confirmed before live traffic. The baseline values below carry forward the previous guide; they are initial integration limits, not a statement of total platform capacity.

LimitBaseline / agreement
Sustained request rate5 QPS for a new connection unless otherwise issued
Burst capacity10 requests; window and replenishment semantics recorded on the connection sheet
Body size262,144 bytes for the uncompressed JSON body; larger requests receive 413
Concurrent in-flight requestsExplicit numeric limit issued before activation
Impressions per requestExplicit numeric limit issued before activation; pods must fit it
Limit scopeSpecify account, credential or connection scope; key rotation must not accidentally multiply account capacity
TransportHTTPS JSON and persistent connections; compression and additional encodings require explicit support

Rate/concurrency rejection is 429 with Retry-After. Apply backoff to subsequent opportunities and discard expired ones. Do not configure uncontrolled retries that multiply the same auction.

Increase traffic only after reviewing p50/p95/p99 latency, timeout/error rates, bid-to-render conversion, tracking delivery and financial reconciliation. One continuous 5-QPS stream is approximately 432,000 requests per day; those requests are not equivalent to impressions or revenue.

9Not supported

This matrix defines the v1 scope. A supported row still requires the relevant platform, creative profile and privacy path to be enabled on the connection sheet.

Capabilityv1 scope
CTV instream videoSupported target scope on verified platforms
Web and mobile in-app videoSupported target scope on enabled platforms
Web and mobile in-app bannerSupported target scope with an agreed HTML/SDK renderer
CTV banner / nativeNot supported
Native on any channelNot supported
Audio-only inventoryOutside this guide’s supported scope
Structured video podsSupported target scope with one impression per slot and validated durations
Dynamic or hybrid podsNot supported; valid unsupported opportunities are declined
VPAID on CTVNot supported
Currencies other than USDNot supported; no FX conversion
Multiple media objects in one impressionNot supported by this v1 integration profile
PMP / deals, iOS-specific measurement, newer optional featuresNot certified by these examples; require separate agreement and verification
Direct browser/app use of authentication secretsNot supported; this is a server-to-server interface

Well-formed unsupported media or pod opportunities are declined according to §3. Invalid requests, malformed signals or unsupported request currencies receive the documented validation response. Do not interpret an unsupported feature as a reason to mislabel the inventory.

10Onboarding

  1. Agree the connection. Register inventory, selling relationships, markets, device classes, media types and privacy paths. Choose the auth mode and response profile. IP pinning is optional for both modes; provide an egress list only if you enable it.
  2. Prepare authorisation. Verify the relevant store/developer identity, ads.txt/app-ads.txt and selling-system seller records. Confirm the complete chain and demand-route node limits.
  3. Issue sandbox access. AdCrew supplies the isolated sandbox URL, credentials, canonical signing path and allowed fixtures. Do not guess a sandbox hostname or test against a production token.
  4. Run the agreed test cases. Exercise authentication, request validation, a canned bid, creative rendering, tracking and no-bid/error paths without real demand spend or live billing.
  5. Approve the live connection sheet. Record measured results, actual limits and the deployed build. Resolve differences between this contract and the implementation before sharing a final production specification.
  6. Activate a limited pilot. Issue separate live credentials and real authorised signals; begin at 1–5 QPS or the agreed rate. Step up when performance and financial records reconcile.

Connection sheet · completed during onboarding

ItemRecorded value / decision
Partner and ownerLegal entity, operational contact and escalation channel
Environment and endpointsIssued sandbox URL; production URL; region; health endpoint
Implementation referenceDeployed build identifier, guide revision and supported dated OpenRTB 2.6 revision
AuthenticationSigned headers or URL token; credential reference only; canonical signing path if relevant
IP pinningOptional for both modes. Record enabled or disabled; record egress ranges only when enabled
Response representationStandard VAST/HTML markup or explicitly tested URL compatibility profile
Test behaviourSandbox isolated from live demand/billing; production rejects test:1
Inventory and identityAuthorised app/store or domains, seller IDs, upstream ASIs, node distribution and route limits
Privacy and platformsEnabled jurisdictions and parsing/enforcement paths; IFA-absent, masked-IP and IPv6-only behaviour; supported OS/players/SSAI
Limits and timingQPS, burst semantics, concurrency, max impressions, payload size, admission budget and timeout targets
Serving and measurementWin trigger, allowed prefetch, billable event, creative TTL, event deadline, expiry response and deduplication window
Operations and commerceReporting access, UTC conventions, discrepancy/adjustment process, retention, payment terms, support and escalation

The template intentionally contains no invented sandbox endpoint, contact address, SLA, capacity figure or payment commitment. AdCrew supplies the actual values privately before activation.

Release verification

Version 7 must be checked against the running service. These are acceptance requirements, not claims that the tests have already passed:

  • Valid requests pass in both authentication modes with IP pinning disabled. When optionally enabled, the allowlist admits the configured egress and rejects other egress without changing the viewer-IP rules.
  • Signed requests reject changed bodies, invalid timestamps and replayed nonces; key rotation preserves the agreed access and rate policy.
  • test:1 cannot reach live demand or create live billables. Production rejects test requests, and sandbox fixtures remain isolated.
  • Complete channel examples pass in the fixture sandbox; production examples use actual authorised properties and truthful platform identifiers.
  • The active standard-markup or URL profile renders on each named partner platform. Do not mark Aniview, Adtelligent, SmartHub or another platform compatible without a recorded test.
  • Net floor and currency rules survive normalisation, privacy filtering and rounding. Missing required country cannot erase the floor.
  • Direct and intermediary chains produce the correct seller path without truncation; restricted or incomplete routes follow the agreed eligibility policy.
  • Privacy denial/absence paths remove the correct fields and prevent unauthorised routing. Exact pod durations and advertiser deduplication behave as contracted.
  • HTTP and seatnonbid.statuscode behaviour matches the examples, including partial bids and empty all-no-bid responses.
  • Repeated and late creative/event requests behave as agreed across instances and restarts. Reports reproduce the per-impression payable and identify any approved adjustments.

Support and incident information

Use the operational contact and escalation channel supplied on your connection sheet. Include environment, request ID, exact UTC timestamp with milliseconds, HTTP status, returned trace/edge reference and a minimal redacted request. Include the affected app/domain and first occurrence when relevant. Do not attach keys, signatures, token URLs or unnecessary viewer identifiers.

Version history

RevisionChanges
v7 · September 2026Makes IP pinning optional in both modes; corrects device/API examples, test isolation, markup profiles, floor semantics, country/currency rules, privacy handling, app-ads.txt discovery, Schain accounting and no-bid fields. Adds complete downloadable examples, offline syntax colours, copy controls, pod and billing guidance, connection sheet and acceptance requirements.
v6 · September 2026Previous supplied integration guide; documented the managed URL creative representation.

Standards and implementation references

The connection sheet identifies the revision actually supported. These references define field meanings; they do not certify AdCrew or any partner implementation.