IAB Agentic Advertising API

The canonical wire protocol between IAB Tech Lab's buyer and seller agents, published from the iab-agentic-primitives repository as an OpenAPI 3.1 document (catalog, quote-to-book deal flow, negotiation, change requests, A2A JSON-RPC messaging and Agent Card discovery) plus sixteen JSON Schema primitives (Account, Agent, Deal, Line, MediaKit, Negotiation, Order, Product, Proposal and others). Pre-release (0.1.0 / v0.5.1 tag) ahead of a 1.0 IAB Tech Lab standardization.

Operations 13

GET /products Paginated product catalog (filtering is client-side; no /products/search) #
GET /products/{product_id} Product detail (the Product primitive, no wrapper) #
POST /products/avails Availability + pricing query (OpenDirect 2.1 spec dialect and legacy simplified profile) #
POST /api/v1/quotes Request a non-binding quote (money-mutating; idempotency_key required) #
GET /api/v1/quotes/{quote_id} Retrieve a quote #
POST /api/v1/deals Book a deal from a quote (money-mutating; idempotency_key required) #
GET /api/v1/deals/{deal_id} Retrieve a deal #
POST /api/v1/change-requests Post-booking modification (money-mutating; idempotency_key required). Makegoods (change_type=makegood, typed MakegoodDetails) and cancellations (change_type=cancellation) ride this #
POST /api/v1/negotiations/messages One negotiation move: offer/counter/accept/decline via the required action enum (FD-5). Replaces POST /proposals/{id}/counter and its bare-price payload. Money-mutating; idempotenc #
GET /api/v1/negotiations/{negotiation_id} Full negotiation history (the Negotiation primitive) #
POST /a2a/jsonrpc A2A JSON-RPC endpoint, ONE method: message/send (the A2A-spec dialect). The retired method "call" MUST be answered with JSON-RPC error -32601. #
GET /.well-known/agent.json Agent Card for A2A discovery — the shared Agent primitive; ONE card schema for both agents. trust_status is registry-verified, never self-asserted (a self-served card carries "unkn #
POST /registry/agents/discover Fetch and register a counterparty's card by base URL #

Documentation

Specifications

Schemas & Data

📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-deal.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-order.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-product.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-negotiation.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-proposal.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-mediakit.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-agent.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-line.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-account.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-organization.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-creative.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-creativeapproval.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-assignment.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-changerequest.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-consentcontext.json
📊
JSONSchema
https://raw.githubusercontent.com/api-evangelist/iab-tech-lab/refs/heads/main/json-schema/iab-tech-lab-agentic-primitive-decisionrecord.json

Other Resources

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/agentic-advertising-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

iab-tech-lab-agentic-advertising-api-openapi.yaml Raw ↑
# OpenAPI 3.1 fragment for the IAB agentic-advertising protocol surfaces
# (EP-1.3). This document is normative for paths, methods, and the schema
# each request/response uses; the referenced JSON Schemas are the exported
# artifacts under ../jsonschema/ (primitives) and ../jsonschema/protocol/
# (protocol messages), which are drift-guarded against the Python
# reference implementation in CI.
#
# Conventions:
# - Every error response, any status, is the ONE structured envelope
#   (ErrorEnvelope: {"detail": {"error": <code>, "message", "unsupported"}}).
# - Money-mutating request bodies carry a required idempotency_key (FD-12):
#   same key -> same response, no duplicate side effects.
# - Wire schemas are must-ignore-unknown-fields (FD-13); the x_ field-name
#   prefix is reserved for vendor extensions.
# - There is deliberately NO POST /products/search (plan §7 amendment 3):
#   the buyer filters client-side over the ProductListResponse fields.
# - Reconciliation notes per surface: PROTOCOL_RECONCILIATION.md.
openapi: 3.1.0
info:
  title: IAB Agentic Advertising API
  version: 0.1.0
  description: >-
    Canonical wire protocol between the IAB Tech Lab buyer and seller
    agents: catalog, quote->book deal flow, negotiation, change requests,
    A2A (Agent-to-Agent protocol) JSON-RPC messaging, and Agent Card
    discovery.
paths:
  /products:
    get:
      operationId: listProducts
      summary: Paginated product catalog (filtering is client-side; no /products/search)
      parameters:
        - name: limit
          in: query
          schema: {type: integer, minimum: 1, maximum: 500, default: 50}
        - name: offset
          in: query
          schema: {type: integer, minimum: 0, default: 0}
      responses:
        "200":
          description: Page of products with pagination echo.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ProductListResponse.json"
  /products/{product_id}:
    get:
      operationId: getProduct
      summary: Product detail (the Product primitive, no wrapper)
      parameters:
        - name: product_id
          in: path
          required: true
          schema: {type: string}
      responses:
        "200":
          description: The product.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/Product.json"
        "404":
          $ref: "#/components/responses/Error"
  /products/avails:
    post:
      operationId: checkAvails
      summary: >-
        Availability + pricing query (OpenDirect 2.1 spec dialect and
        legacy simplified profile)
      description: >-
        Honest-availability check, served in BOTH dialects. Servers accept
        the published OpenDirect 2.1 ProductAvailsSearch (multi-product
        productids array with required accountid/advertiserbrandid) AND
        the legacy single-product simplified profile, discriminated by
        productids (array, spec) vs productid (scalar, legacy). The
        response dialect follows the request dialect — spec requests get
        the spec 'avails' collection envelope of Avails records (per the
        OpenDirect Collection Objects table) with availsstatus semantics
        (Available / Partially Available / Unavailable, enumerated
        reasons); legacy requests get the legacy single-object response
        unchanged, so v2.1.0-v2.2.1 payload round-trips are preserved.
        Legacy policy (unchanged): availableImpressions is REQUIRED
        (uncapped products report the requested volume as available).
        deliveryConfidence is OPTIONAL and OMITTED entirely when the seller
        has no forecast data source — emitters MUST NOT fabricate a value
        or pad with null (readers tolerate null from pre-contract
        emitters). guaranteedImpressions is present ONLY for PG-capable
        (Programmatic Guaranteed) products. Money fields on this surface
        are floats — a documented FD-11 exception preserving the shipped
        OpenDirect 2.1 wire dialect; migration to Money micros is reserved
        for the next major version.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "../jsonschema/protocol/ProductAvailsSearch.json"
                - $ref: "../jsonschema/protocol/AvailsRequest.json"
      responses:
        "200":
          description: >-
            Availability and pricing derived from catalog data. Spec
            requests: the 'avails' collection envelope (one Avails record
            per requested product). Legacy requests: the legacy
            single-object response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "../jsonschema/protocol/AvailsCollection.json"
                  - $ref: "../jsonschema/protocol/AvailsResponse.json"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          description: >-
            Unpriceable product (neither base nor floor CPM) or request
            validation failure — never a fabricated price.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ErrorEnvelope.json"
  /api/v1/quotes:
    post:
      operationId: createQuote
      summary: Request a non-binding quote (money-mutating; idempotency_key required)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "../jsonschema/protocol/QuoteRequest.json"
      responses:
        "201":
          description: Quote envelope wrapping the Quote primitive.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/QuoteResponse.json"
        "400":
          description: >-
            Validation failure, or the FD-6 structured capability rejection
            (error=unsupported_capability with the unsupported list, e.g.
            linear_tv).
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ErrorEnvelope.json"
        "404":
          $ref: "#/components/responses/Error"
  /api/v1/quotes/{quote_id}:
    get:
      operationId: getQuote
      summary: Retrieve a quote
      parameters:
        - name: quote_id
          in: path
          required: true
          schema: {type: string}
      responses:
        "200":
          description: Quote envelope.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/QuoteResponse.json"
        "404":
          $ref: "#/components/responses/Error"
        "410":
          description: Quote expired (error=quote_expired).
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ErrorEnvelope.json"
  /api/v1/deals:
    post:
      operationId: bookDeal
      summary: Book a deal from a quote (money-mutating; idempotency_key required)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "../jsonschema/protocol/DealBookingRequest.json"
      responses:
        "201":
          description: Deal envelope wrapping the Deal primitive.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/DealBookingResponse.json"
        "400":
          description: Validation failure or FD-6 capability rejection.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ErrorEnvelope.json"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          description: Quote already booked / concurrent conflict (error=contention).
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ErrorEnvelope.json"
        "410":
          description: Quote expired (error=quote_expired).
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ErrorEnvelope.json"
  /api/v1/deals/{deal_id}:
    get:
      operationId: getDeal
      summary: Retrieve a deal
      parameters:
        - name: deal_id
          in: path
          required: true
          schema: {type: string}
      responses:
        "200":
          description: Deal envelope.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/DealBookingResponse.json"
        "404":
          $ref: "#/components/responses/Error"
  /api/v1/change-requests:
    post:
      operationId: createChangeRequest
      summary: >-
        Post-booking modification (money-mutating; idempotency_key
        required). Makegoods (change_type=makegood, typed MakegoodDetails)
        and cancellations (change_type=cancellation) ride this surface;
        the per-deal /makegoods and /cancel sub-routes are retired (FD-6).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "../jsonschema/protocol/ChangeRequestCreate.json"
      responses:
        "201":
          description: Envelope wrapping the ChangeRequest primitive.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ChangeRequestResponse.json"
        "400":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /api/v1/negotiations/messages:
    post:
      operationId: sendNegotiationMessage
      summary: >-
        One negotiation move: offer/counter/accept/decline via the required
        action enum (FD-5). Replaces POST /proposals/{id}/counter and its
        bare-price payload. Money-mutating; idempotency_key required.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "../jsonschema/protocol/NegotiationMessage.json"
      responses:
        "200":
          description: The seller's move for this round.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/NegotiationRoundResponse.json"
        "400":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          description: >-
            Terminal negotiation (error=negotiation_closed) or round-number
            mismatch (error=contention).
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/ErrorEnvelope.json"
  /api/v1/negotiations/{negotiation_id}:
    get:
      operationId: getNegotiation
      summary: Full negotiation history (the Negotiation primitive)
      parameters:
        - name: negotiation_id
          in: path
          required: true
          schema: {type: string}
      responses:
        "200":
          description: The negotiation with its round history.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/Negotiation.json"
        "404":
          $ref: "#/components/responses/Error"
  /a2a/jsonrpc:
    post:
      operationId: a2aMessageSend
      summary: >-
        A2A JSON-RPC endpoint, ONE method: message/send (the A2A-spec
        dialect). The retired method "call" MUST be answered with JSON-RPC
        error -32601.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "../jsonschema/protocol/JsonRpcRequest.json"
      responses:
        "200":
          description: JSON-RPC response (exactly one of result/error).
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/JsonRpcResponse.json"
  /.well-known/agent.json:
    get:
      operationId: getAgentCard
      summary: >-
        Agent Card for A2A discovery — the shared Agent primitive; ONE
        card schema for both agents. trust_status is registry-verified,
        never self-asserted (a self-served card carries "unknown").
      responses:
        "200":
          description: The agent's card.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/Agent.json"
  /registry/agents/discover:
    post:
      operationId: discoverAgent
      summary: Fetch and register a counterparty's card by base URL
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "../jsonschema/protocol/AgentDiscoveryRequest.json"
      responses:
        "200":
          description: Registry-verified trust result for the agent.
          content:
            application/json:
              schema:
                $ref: "../jsonschema/protocol/AgentTrustVerification.json"
        "404":
          $ref: "#/components/responses/Error"
components:
  responses:
    Error:
      description: >-
        Structured error envelope: {"detail": {"error": <ErrorCode>,
        "message": "...", "unsupported": [...]}}.
      content:
        application/json:
          schema:
            $ref: "../jsonschema/protocol/ErrorEnvelope.json"