Docs / Reference

Every Admin API operation

Find Admin API operations and their request and response schemas. Search by name or path, follow schema references, or download the OpenAPI contract to use in your integration.

Authentication and client conventions · Examples and prompts · Download OpenAPI

401 operations. Your API key, role, tenant, and enabled features determine which operations you can call. References beginning with #/components/ resolve in the component definitions below or in the downloaded contract.

401 operations

GET getAuthConfig
/v1/auth/config

Read the public authentication settings, including whether self-service signup is enabled.

schemas/AuthConfigresponses/Error

Parameters, request and responses

{
  "parameters": [],
  "responses": {
    "200": {
      "description": "Auth config.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AuthConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": []
}
POST authSignup
/v1/auth/signup

Start self-service signup by sending a magic-link challenge. Only a hash of the challenge is stored. The tenant and first admin are created after verification. Requires RIPTIDE_ALLOW_PUBLIC_SIGNUP.

parameters/IdempotencyKeyschemas/AuthSignupRequestschemas/AuthAcceptedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AuthSignupRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Always ok when accepted (enumerate-safe).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AuthAccepted"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": []
}
POST authVerify
/v1/auth/verify

Verify a magic-link token and issue an rt_sess_ session bearer. If the verified email belongs to multiple tenants, the session includes memberships[] and tenant_choice_required: true so the client can request a tenant selection. Membership information is returned only after verification.

Invite redemption atomically revalidates the pending, unrevoked, unexpired challenge, non-archived tenant and active user, grants the permitted role, and consumes the invite. Publisher invites require a non-archived publisher in the same tenant. An existing user must already have that same non-null publisher binding; a missing or different binding returns 409 CONFLICT with a publisher_id field hint and never implicitly rebinds the user. An invalid, missing or archived invited publisher returns BAD_INPUT. An invalid, expired or revoked challenge, inactive user, or archived tenant returns 401. For a keyed verification, token consumption and its token-bound retry receipt commit together; invite user creation and the role grant share that commit. Receipt storage failures leave the challenge retryable. A retry after session creation or response failure revalidates current identity and permissions before issuing a fresh session. Signup provisioning uses its existing resumable workflow before this atomic verification step; workspace provisioning is not part of the verification transaction.

parameters/IdempotencyKeyschemas/AuthVerifyRequestschemas/AuthSessionresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AuthVerifyRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Session issued.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AuthSession"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": []
}
GET getPublicBranding
/v1/branding

Read the product name, logo, favicon, and theme colors for a console host before login. The host is matched against the tenant's serving_domain or console host mapping. Hostnames and other tenant fields are excluded. Unknown hosts return the platform defaults with HTTP 200, so callers cannot use a 404 response to identify registered hosts.

schemas/PublicBrandingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "name": "host",
      "in": "query",
      "required": true,
      "description": "The console hostname the browser loaded from (lower-case, no scheme or port).",
      "schema": {
        "type": "string",
        "minLength": 1,
        "maxLength": 253
      }
    }
  ],
  "responses": {
    "200": {
      "description": "The public branding subset for the host (platform defaults for an unknown host).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PublicBranding"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": []
}
POST authLogout
/v1/auth/logout

Revoke the current session bearer.

parameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Revoked (or already gone)."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET authMe
/v1/auth/me

Current authenticated actor (user, tenant, roles, entitlements).

schemas/AuthMeresponses/Error

Parameters, request and responses

{
  "parameters": [],
  "responses": {
    "200": {
      "description": "Current session identity.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AuthMe"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST revokeAllSessions
/v1/auth/sessions/revoke-all

End all console sessions of the signed-in actor, including the current session. The actor is resolved from the session; callers cannot select an actor with a tenant_id parameter.

parameters/IdempotencyKeyschemas/SessionsRevokedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Number of sessions revoked.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SessionsRevoked"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listGeoReference
/v1/reference/geo

Read distinct countries, regions, metros, and cities from the loaded IP geolocation dataset. Any authenticated actor can read this shared dictionary. Returns 503 with a retryable hint until a dataset is loaded.

schemas/GeoReferenceLevelparameters/Limitparameters/Cursorschemas/GeoReferencePageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "name": "level",
      "in": "query",
      "required": false,
      "schema": {
        "$ref": "#/components/schemas/GeoReferenceLevel"
      },
      "description": "Hierarchy level to list (default city)."
    },
    {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "maxLength": 64
      },
      "description": "Case-insensitive substring match on the entry name (a metro code is matched by prefix)."
    },
    {
      "name": "country",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "maxLength": 64
      },
      "description": "Narrow to a country (ISO 3166-1 alpha-2, case-insensitive)."
    },
    {
      "name": "region",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "maxLength": 64
      },
      "description": "Narrow to a region code within country."
    },
    {
      "name": "metro",
      "in": "query",
      "required": false,
      "schema": {
        "type": "integer",
        "format": "int32",
        "minimum": 1
      },
      "description": "Narrow to a metro (DMA) code."
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "One page of dictionary entries plus the dataset they came from.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/GeoReferencePage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCells
/v1/operator/cells

List cells with their region, tier, status, and endpoints. Operator access required.

parameters/Limitparameters/Cursorschemas/CellListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "Cells sorted by id.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CellList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST assignTenantRatePlan
/v1/operator/tenants/{tenant_id}/rate-plan

Assign a platform rate plan to a tenant and, by default, apply the plan's entitlement pack. Operator access required.

parameters/TenantIdparameters/IdempotencyKeyschemas/TenantRatePlanAssignschemas/PlatformRatePlanresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TenantRatePlanAssign"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The tenant's rate plan after assignment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformRatePlan"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listTenants
/v1/operator/tenants

List tenants (operator only).

parameters/Limitparameters/Cursorschemas/TenantListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of tenants.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createTenant
/v1/operator/tenants

Create a tenant (operator only).

parameters/IdempotencyKeyschemas/TenantCreateschemas/Tenantresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TenantCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Tenant"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST onboardTenant
/v1/operator/onboarding/tenants

Create a tenant, apply entitlements, generate a sealing key, create the first admin user, and optionally provision a custom serving domain. The workflow is idempotent by Idempotency-Key and compensates for completed steps if a later step fails.

parameters/IdempotencyKeyschemas/OnboardTenantRequestschemas/TenantOnboardingResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OnboardTenantRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Onboarded tenant resources.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantOnboardingResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getTenant
/v1/operator/tenants/{tenant_id}

Get a tenant (operator only).

schemas/Tenantresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "The tenant.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Tenant"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateTenant
/v1/operator/tenants/{tenant_id}

Update a tenant's branding or entitlements. Operator access required. A supplied entitlements array replaces the entire entitlement set, including the ssp, dsp, and ad_server module permissions. Supplied branding replaces the product name and serving, event, and sync hostnames used by the console and hostname-based tenant lookup.

parameters/TenantIdparameters/IdempotencyKeyschemas/TenantUpdateschemas/Tenantresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TenantUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Tenant"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getTenantHealth
/v1/tenants/{tenant_id}/health

Read tenant health, including the serving plan version when a plan store is connected, per-endpoint error rates, and governor shed counts from process counters. When ClickHouse is configured, the response also includes requests, fills, impressions, revenue_net, and fill_rate for the same window. Those metric fields are omitted when ClickHouse is not configured.

schemas/TenantHealthresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "The tenant's current health snapshot.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantHealth"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAgentIdentities
/v1/tenants/{tenant_id}/agent-identities

List the tenant's registered agent identities, newest first.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/LifecycleStatusschemas/AgentIdentityListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Only identities in this lifecycle status.",
      "schema": {
        "$ref": "#/components/schemas/LifecycleStatus"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of agent identities.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AgentIdentityList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createAgentIdentity
/v1/tenants/{tenant_id}/agent-identities

Register a named agent identity for an MCP or A2A client, bind its public key, and set its autonomy band. New actions use the tenant's configured write default. The response includes the active public key; the agent proves possession of its private key at the gateway.

parameters/TenantIdparameters/IdempotencyKeyschemas/AgentIdentityCreateschemas/AgentIdentityresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AgentIdentityCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The registered identity.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AgentIdentity"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAgentIdentity
/v1/tenants/{tenant_id}/agent-identities/{agent_identity_id}

Get one agent identity with its keys, band and kill-switch state.

schemas/AgentIdentityresponses/Errorparameters/TenantIdparameters/AgentIdentityId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AgentIdentityId"
    }
  ],
  "responses": {
    "200": {
      "description": "The agent identity.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AgentIdentity"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST rotateAgentIdentityKey
/v1/tenants/{tenant_id}/agent-identities/{agent_identity_id}/rotate-key

Register a new public key for an agent identity and revoke its previously active key. Calls signed with the revoked key are rejected after this operation returns. Other identity settings are unchanged.

parameters/TenantIdparameters/AgentIdentityIdparameters/IdempotencyKeyschemas/AgentIdentityKeyRegisterschemas/AgentIdentityresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AgentIdentityId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AgentIdentityKeyRegister"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The identity with the new active key.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AgentIdentity"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST setAgentIdentityBand
/v1/tenants/{tenant_id}/agent-identities/{agent_identity_id}/band

Change an agent identity's autonomy band. Each tool call checks the current band, so a demotion applies to the agent's next call. The reason is recorded in the audit log.

parameters/TenantIdparameters/AgentIdentityIdparameters/IdempotencyKeyschemas/AgentIdentityBandSetschemas/AgentIdentityresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AgentIdentityId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AgentIdentityBandSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The identity on its new band.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AgentIdentity"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST tripAgentKillSwitch
/v1/tenants/{tenant_id}/agent-identities/{agent_identity_id}/kill-switch/trip

Trip an agent identity's kill switch. Subsequent mutating tool calls return a typed error until resetAgentKillSwitch is called. Read-only calls remain available. Anomaly alerts can also trip the switch automatically. A manual trip records the actor and reason.

parameters/TenantIdparameters/AgentIdentityIdparameters/IdempotencyKeyschemas/AgentKillSwitchRequestschemas/AgentIdentityresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AgentIdentityId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AgentKillSwitchRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The identity with the switch tripped.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AgentIdentity"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST resetAgentKillSwitch
/v1/tenants/{tenant_id}/agent-identities/{agent_identity_id}/kill-switch/reset

Reset a tripped kill switch so the identity may call tools again; the reason is audited.

parameters/TenantIdparameters/AgentIdentityIdparameters/IdempotencyKeyschemas/AgentKillSwitchRequestschemas/AgentIdentityresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AgentIdentityId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AgentKillSwitchRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The identity with the switch reset.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AgentIdentity"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listLlmUsage
/v1/tenants/{tenant_id}/llm-usage

List language-model calls made on the tenant's behalf, including the prompt digest, token counts, and metered cost. Results are newest first and use cursor pagination.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/LlmUsageListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "surface",
      "in": "query",
      "required": false,
      "description": "Only calls made by this surface (e.g. insight_ask, playbook, creative_agent, diagnosis_agent).",
      "schema": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64
      }
    },
    {
      "name": "since",
      "in": "query",
      "required": false,
      "description": "Only calls at or after this instant.",
      "schema": {
        "type": "string",
        "format": "date-time"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of ledger rows.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LlmUsageList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPrivacyRequests
/v1/tenants/{tenant_id}/privacy-requests

List data-subject privacy requests, newest first, with cursor pagination.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/PrivacyRequestStatusschemas/PrivacyRequestKindschemas/PrivacyRequestListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Only requests in this status.",
      "schema": {
        "$ref": "#/components/schemas/PrivacyRequestStatus"
      }
    },
    {
      "name": "kind",
      "in": "query",
      "required": false,
      "description": "Only requests of this kind.",
      "schema": {
        "$ref": "#/components/schemas/PrivacyRequestKind"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of privacy requests.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PrivacyRequestList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createPrivacyRequest
/v1/tenants/{tenant_id}/privacy-requests

Create an access, erasure, or opt-out request for an opaque user key. The key is hashed before storage in subject_key_hash. Processing is asynchronous and covers profiles, memberships, and event retention; the request records the processing evidence. New requests have status RECEIVED.

parameters/TenantIdparameters/IdempotencyKeyschemas/PrivacyRequestCreateschemas/PrivacyRequestresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PrivacyRequestCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The filed request.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PrivacyRequest"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPrivacyRequest
/v1/tenants/{tenant_id}/privacy-requests/{privacy_request_id}

Get one privacy request with its status and evidence.

schemas/PrivacyRequestresponses/Errorparameters/TenantIdparameters/PrivacyRequestId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PrivacyRequestId"
    }
  ],
  "responses": {
    "200": {
      "description": "The privacy request.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PrivacyRequest"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST loadSampleData
/v1/tenants/{tenant_id}/sample-data

Load sample publishers, placements, advertisers, orders, line items, creatives, audiences, and a fee schedule into a sandbox tenant. Requires sandbox: true; other tenants receive 409 CONFLICT. Loading again replaces the previous sample set. Returns 202 while processing continues.

parameters/TenantIdparameters/IdempotencyKeyschemas/SampleDataLoadResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "202": {
      "description": "What was loaded.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SampleDataLoadResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAuditLog
/v1/tenants/{tenant_id}/audit-log

List recent immutable audit records for a tenant. Requires operability.read and applies tenant row-level security. The same records are available through the riptide.operability.query_audit_trail MCP tool.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/AuditLogListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of audit envelopes, most recent first.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AuditLogList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET runDoctor
/v1/tenants/{tenant_id}/operability/doctor

Diagnose the console process configuration, including required environment variables and settings that must be supplied together, such as a sealing key and its ID. The CLI and riptide.operability.run_doctor MCP tool use the same diagnostic checks.

parameters/TenantIdschemas/DoctorResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "env_var",
      "in": "query",
      "required": false,
      "description": "Optional override of which env vars to check; defaults to libs/doctor.EnvVars when omitted.\n",
      "schema": {
        "type": "array",
        "items": {
          "type": "string"
        }
      }
    }
  ],
  "responses": {
    "200": {
      "description": "The doctor run's checks and any misconfigurations found.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DoctorResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST explainRequest
/v1/tenants/{tenant_id}/operability/explain

Explain a supplied decision trace with its stages and winner rationale. For example, use a trace captured from a debug=1 serving response. Complete decision traces cannot be retrieved by request ID. When decision_trace is omitted and request_id is supplied, a configured ClickHouse connection can return the request's ad-event timeline instead of a decision funnel.

schemas/ExplainRequestInputschemas/ExplainResultresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": false,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ExplainRequestInput"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The rendered explanation.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExplainResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET diagnoseServing
/v1/tenants/{tenant_id}/diagnostics/serving

Read blocking issues, eligibility checks, and a serving diagnosis for one line item. The summary matches the text returned by riptide.operability.diagnose_delivery. This operation does not change the line item.

parameters/TenantIdschemas/ServingDiagnosisresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "line_item_ref",
      "in": "query",
      "required": true,
      "description": "Line item reference code to diagnose (the same key diagnoseDelivery takes).",
      "schema": {
        "type": "string",
        "minLength": 1
      }
    }
  ],
  "responses": {
    "200": {
      "description": "The diagnosis.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ServingDiagnosis"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST diagnoseDelivery
/v1/tenants/{tenant_id}/operability/diagnose-delivery

Diagnose a line item's delivery using its current serving status, flight window, and audience configuration. The riptide.operability.diagnose_delivery MCP tool uses the same checks.

schemas/DiagnoseDeliveryInputschemas/DiagnoseDeliveryResultresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DiagnoseDeliveryInput"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The blocking issues found (if any) and the checks that were run.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DiagnoseDeliveryResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST preflightChange
/v1/tenants/{tenant_id}/operability/preflight

Preview the structural difference between the current and proposed configuration, with warnings for unchanged values or unrecognized kinds. This check does not recompile the serving plan or evaluate the change's effect on delivery.

schemas/PreflightChangeInputschemas/PreflightChangeResultresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PreflightChangeInput"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Whether the change would apply, warnings, and the before/after diff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PreflightChangeResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateTenantAudioToVideo
/v1/tenants/{tenant_id}/audio-to-video

Update the tenant's audio-to-video settings or its advertiser-domain overrides. Configuration follows the tenant, publisher, brand, and platform-default hierarchy. Tenant access is sufficient; enabling the feature requires the audio_to_video entitlement.

parameters/TenantIdparameters/IdempotencyKeyschemas/TenantAudioToVideoUpdateschemas/Tenantresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TenantAudioToVideoUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Tenant"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET previewAdsTxt
/v1/tenants/{tenant_id}/supply-transparency/preview/ads-txt

Preview the generated ads.txt/app-ads.txt document for a publisher. Requires `supply.read`.

parameters/TenantIdschemas/SupplyDocumentPreviewresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "publisher_id",
      "in": "query",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Generated ads.txt/app-ads.txt preview.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyDocumentPreview"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET previewSellersJson
/v1/tenants/{tenant_id}/supply-transparency/preview/sellers-json

Preview the generated sellers.json document served canonically from /sellers.json. Requires `supply.read`.

schemas/SupplyDocumentPreviewresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Generated sellers.json preview.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyDocumentPreview"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST verifySupplyDocument
/v1/tenants/{tenant_id}/supply-transparency/verify

Crawl and verify one ads.txt, app-ads.txt, or sellers.json document, persisting the latest check fact for bid-time policy decisions. Requires `supply.write`.

parameters/TenantIdparameters/IdempotencyKeyschemas/SupplyDocumentVerifyRequestschemas/SupplyDocumentCheckresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/SupplyDocumentVerifyRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Latest check fact.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyDocumentCheck"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listSupplyDocumentChecks
/v1/tenants/{tenant_id}/supply-transparency/checks

List the tenant's latest supply transparency checks. Requires `supply.read`.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/SupplyDocumentKindschemas/SupplyDocumentSubjectTypeschemas/SupplyDocumentCheckListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "kind",
      "in": "query",
      "required": false,
      "schema": {
        "$ref": "#/components/schemas/SupplyDocumentKind"
      }
    },
    {
      "name": "subject_type",
      "in": "query",
      "required": false,
      "schema": {
        "$ref": "#/components/schemas/SupplyDocumentSubjectType"
      }
    },
    {
      "name": "subject_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of supply document check facts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyDocumentCheckList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getSupplyDocumentCheck
/v1/tenants/{tenant_id}/supply-transparency/checks/{check_id}

Read one persisted supply transparency check fact. Requires `supply.read`.

schemas/SupplyDocumentCheckresponses/Errorparameters/TenantIdparameters/SupplyDocumentCheckId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/SupplyDocumentCheckId"
    }
  ],
  "responses": {
    "200": {
      "description": "Supply document check fact.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyDocumentCheck"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
DELETE deleteSupplyDocumentCheck
/v1/tenants/{tenant_id}/supply-transparency/checks/{check_id}

Delete one supply transparency check, ending its scheduled re-crawl obligation. The subject's snapshot history is retained (drift audit trail). Requires `supply.write`.

parameters/TenantIdparameters/SupplyDocumentCheckIdparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/SupplyDocumentCheckId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Check deleted; the subject will no longer be re-crawled."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listSupplyDocumentSnapshots
/v1/tenants/{tenant_id}/supply-transparency/snapshots

List crawled supply document snapshots (drift history) newest-first. Bodies are omitted; fetch one snapshot for its full document body. Requires `supply.read`.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/SupplyDocumentKindschemas/SupplyDocumentSubjectTypeschemas/SupplyDocumentSnapshotListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "kind",
      "in": "query",
      "required": false,
      "schema": {
        "$ref": "#/components/schemas/SupplyDocumentKind"
      }
    },
    {
      "name": "subject_type",
      "in": "query",
      "required": false,
      "schema": {
        "$ref": "#/components/schemas/SupplyDocumentSubjectType"
      }
    },
    {
      "name": "subject_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of supply document snapshots, newest first, without bodies.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyDocumentSnapshotList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getSupplyDocumentSnapshot
/v1/tenants/{tenant_id}/supply-transparency/snapshots/{snapshot_id}

Read one supply document snapshot including its full body, drift diff against the previous snapshot, and structural analysis. Requires `supply.read`.

schemas/SupplyDocumentSnapshotresponses/Errorparameters/TenantIdparameters/SupplyDocumentSnapshotId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/SupplyDocumentSnapshotId"
    }
  ],
  "responses": {
    "200": {
      "description": "Supply document snapshot with body, diff, and analysis.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyDocumentSnapshot"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getSupplyTransparencyHealth
/v1/tenants/{tenant_id}/supply-transparency/health

Aggregate supply-chain transparency health report - verification coverage, per-subject status, structural risk scores, and drift flags across the tenant's latest checks and snapshots. Requires `supply.read`.

schemas/SupplyTransparencyHealthReportresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Aggregated supply transparency health report.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyTransparencyHealthReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPublishers
/v1/tenants/{tenant_id}/publishers

List a tenant's publishers.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/PublisherListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of publishers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PublisherList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createPublisher
/v1/tenants/{tenant_id}/publishers

Create a publisher.

parameters/TenantIdparameters/IdempotencyKeyschemas/PublisherCreateschemas/Publisherresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PublisherCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Publisher"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST bulkImportPublishers
/v1/tenants/{tenant_id}/publishers/bulk-import

Create publishers in a batch and return a result for each row. A failed row does not abort other rows. With dry_run: true, validate required fields and public_id conflicts both inside the batch and against stored publishers without saving changes.

parameters/TenantIdparameters/IdempotencyKeyschemas/PublisherBulkImportRequestschemas/PublisherBulkImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PublisherBulkImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row results (dry-run preview or applied).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PublisherBulkImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPublisher
/v1/tenants/{tenant_id}/publishers/{publisher_id}

Get a publisher.

schemas/Publisherresponses/Errorparameters/TenantIdparameters/PublisherId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    }
  ],
  "responses": {
    "200": {
      "description": "The publisher.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Publisher"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updatePublisher
/v1/tenants/{tenant_id}/publishers/{publisher_id}

Update a publisher.

parameters/TenantIdparameters/PublisherIdparameters/IdempotencyKeyschemas/PublisherUpdateschemas/Publisherresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PublisherUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Publisher"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archivePublisher
/v1/tenants/{tenant_id}/publishers/{publisher_id}/archive

Archive a publisher.

parameters/TenantIdparameters/PublisherIdparameters/IdempotencyKeyschemas/Publisherresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Publisher"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPublisherStatusCounts
/v1/tenants/{tenant_id}/publishers/status-counts

Per-status row counts for the tenant's publishers.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPlacements
/v1/tenants/{tenant_id}/placements

List a tenant's placements.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/PlacementListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of placements.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlacementList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createPlacement
/v1/tenants/{tenant_id}/placements

Create a placement (inactive by default until activated).

parameters/TenantIdparameters/IdempotencyKeyschemas/PlacementCreateschemas/Placementresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PlacementCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Placement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST bulkImportPlacements
/v1/tenants/{tenant_id}/placements/bulk-import

Create placements in a batch and return a result for each row. A failed row does not abort other rows. With dry_run: true, validate required fields and public_id conflicts both inside the batch and against stored placements without saving changes.

parameters/TenantIdparameters/IdempotencyKeyschemas/PlacementBulkImportRequestschemas/PlacementBulkImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PlacementBulkImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row results (dry-run preview or applied).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlacementBulkImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPlacement
/v1/tenants/{tenant_id}/placements/{placement_id}

Get a placement.

schemas/Placementresponses/Errorparameters/TenantIdparameters/PlacementId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    }
  ],
  "responses": {
    "200": {
      "description": "The placement.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Placement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updatePlacement
/v1/tenants/{tenant_id}/placements/{placement_id}

Update a placement (including stitch and demand attachment config).

parameters/TenantIdparameters/PlacementIdparameters/IdempotencyKeyschemas/PlacementUpdateschemas/Placementresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PlacementUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Placement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archivePlacement
/v1/tenants/{tenant_id}/placements/{placement_id}/archive

Archive a placement.

parameters/TenantIdparameters/PlacementIdparameters/IdempotencyKeyschemas/Placementresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Placement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPlacementDecisionFunnel
/v1/tenants/{tenant_id}/placements/{placement_id}/decision-funnel

Read recent placement decision records from ClickHouse and aggregate the counts entering and leaving each stage, including removal reasons. The response includes the sampled records used. Without a configured ClickHouse source, the response contains an empty aggregate and source_configured=false.

parameters/TenantIdparameters/PlacementIdschemas/DecisionFunnelResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 500,
        "default": 100
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Aggregated placement funnel.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DecisionFunnelResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPlacementStatusCounts
/v1/tenants/{tenant_id}/placements/status-counts

Per-status row counts for the tenant's placements.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPlacementMarketplaces
/v1/tenants/{tenant_id}/placements/{placement_id}/marketplaces

List the IDs of marketplaces that include a placement.

parameters/TenantIdparameters/PlacementIdparameters/Limitparameters/Cursorschemas/PlacementMarketplaceMembershipresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The placement's marketplace membership.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlacementMarketplaceMembership"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT setPlacementMarketplaces
/v1/tenants/{tenant_id}/placements/{placement_id}/marketplaces

Replace a placement's full marketplace membership set.

parameters/TenantIdparameters/PlacementIdparameters/IdempotencyKeyschemas/PlacementMarketplaceMembershipresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PlacementMarketplaceMembership"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated membership.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlacementMarketplaceMembership"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPlacementDemandRoutes
/v1/tenants/{tenant_id}/placements/{placement_id}/demand-routes

List demand route IDs explicitly bound to a placement.

parameters/TenantIdparameters/PlacementIdparameters/Limitparameters/Cursorschemas/PlacementDemandRouteMembershipresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The placement's explicit demand-route bindings.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlacementDemandRouteMembership"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT setPlacementDemandRoutes
/v1/tenants/{tenant_id}/placements/{placement_id}/demand-routes

Replace a placement's full explicit demand-route binding set.

parameters/TenantIdparameters/PlacementIdparameters/IdempotencyKeyschemas/PlacementDemandRouteMembershipresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PlacementDemandRouteMembership"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated bindings.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlacementDemandRouteMembership"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET resolvePlacementMarketplaces
/v1/tenants/{tenant_id}/placements/{placement_id}/marketplaces/resolve

Preview the ACTIVE demand routes included through a placement's marketplace memberships. The serving-plan compiler uses the same marketplace-to-route lookup.

schemas/ResolvedMarketplaceRoutesresponses/Errorparameters/TenantIdparameters/PlacementId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    }
  ],
  "responses": {
    "200": {
      "description": "Resolved demand route ids.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResolvedMarketplaceRoutes"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listApps
/v1/tenants/{tenant_id}/apps

List a tenant's apps (app inventory).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/AppListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of apps.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AppList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createApp
/v1/tenants/{tenant_id}/apps

Create an app with optional publisher pricing overrides and demand-partner route approvals.

parameters/TenantIdparameters/IdempotencyKeyschemas/AppCreateschemas/Appresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AppCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/App"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getApp
/v1/tenants/{tenant_id}/apps/{app_id}

Get an app.

schemas/Appresponses/Errorparameters/TenantIdparameters/AppId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AppId"
    }
  ],
  "responses": {
    "200": {
      "description": "The app.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/App"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateApp
/v1/tenants/{tenant_id}/apps/{app_id}

Update an app.

parameters/TenantIdparameters/AppIdparameters/IdempotencyKeyschemas/AppUpdateschemas/Appresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AppId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AppUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/App"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveApp
/v1/tenants/{tenant_id}/apps/{app_id}/archive

Archive an app.

parameters/TenantIdparameters/AppIdparameters/IdempotencyKeyschemas/Appresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AppId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/App"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAppStatusCounts
/v1/tenants/{tenant_id}/apps/status-counts

Per-status row counts for the tenant's apps.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAppLookups
/v1/tenants/{tenant_id}/app-lookups

List cached app lookups that map a publisher_public_id and app bundle to an app or a blocked result.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/AppLookupListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of app lookups.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AppLookupList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createAppLookup
/v1/tenants/{tenant_id}/app-lookups

Create or upsert an app-lookup row (idempotent on tenant+cache_key).

parameters/TenantIdparameters/IdempotencyKeyschemas/AppLookupCreateschemas/AppLookupresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AppLookupCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AppLookup"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAppLookup
/v1/tenants/{tenant_id}/app-lookups/{cache_key}

Get one app-lookup row by cache_key.

schemas/AppLookupresponses/Errorparameters/TenantIdparameters/AppLookupCacheKey

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AppLookupCacheKey"
    }
  ],
  "responses": {
    "200": {
      "description": "The app lookup.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AppLookup"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateAppLookup
/v1/tenants/{tenant_id}/app-lookups/{cache_key}

Update an app-lookup row (blocked flag and resolution targets).

parameters/TenantIdparameters/AppLookupCacheKeyparameters/IdempotencyKeyschemas/AppLookupUpdateschemas/AppLookupresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AppLookupCacheKey"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AppLookupUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AppLookup"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listVerificationVendorConfigs
/v1/tenants/{tenant_id}/verification-vendor-configs

List the tenant's verification vendor slot templates, A through D, used for rendering and reporting.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/VerificationVendorConfigListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of vendor configs.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/VerificationVendorConfigList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createVerificationVendorConfig
/v1/tenants/{tenant_id}/verification-vendor-configs

Create a verification vendor config for one slot (unique per tenant+vendor).

parameters/TenantIdparameters/IdempotencyKeyschemas/VerificationVendorConfigCreateschemas/VerificationVendorConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/VerificationVendorConfigCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/VerificationVendorConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getVerificationVendorConfig
/v1/tenants/{tenant_id}/verification-vendor-configs/{config_id}

Get a verification vendor config.

schemas/VerificationVendorConfigresponses/Errorparameters/TenantIdparameters/VerificationVendorConfigId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/VerificationVendorConfigId"
    }
  ],
  "responses": {
    "200": {
      "description": "The config.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/VerificationVendorConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateVerificationVendorConfig
/v1/tenants/{tenant_id}/verification-vendor-configs/{config_id}

Update a verification vendor config.

parameters/TenantIdparameters/VerificationVendorConfigIdparameters/IdempotencyKeyschemas/VerificationVendorConfigUpdateschemas/VerificationVendorConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/VerificationVendorConfigId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/VerificationVendorConfigUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/VerificationVendorConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
DELETE deleteVerificationVendorConfig
/v1/tenants/{tenant_id}/verification-vendor-configs/{config_id}

Delete a verification vendor config.

parameters/TenantIdparameters/VerificationVendorConfigIdparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/VerificationVendorConfigId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Deleted."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCreativeEventTrackers
/v1/tenants/{tenant_id}/creatives/{creative_id}/event-trackers

List a creative's third-party event trackers.

parameters/TenantIdparameters/CreativeIdparameters/Limitparameters/Cursorschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The creative's trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replaceCreativeEventTrackers
/v1/tenants/{tenant_id}/creatives/{creative_id}/event-trackers

Replace the full set of a creative's event trackers.

parameters/TenantIdparameters/CreativeIdparameters/IdempotencyKeyschemas/EventTrackerSetschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/EventTrackerSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listLineItemEventTrackers
/v1/tenants/{tenant_id}/line-items/{line_item_id}/event-trackers

List a line item's third-party event trackers (applied to all its creatives).

parameters/TenantIdparameters/LineItemIdparameters/Limitparameters/Cursorschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The line item's trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replaceLineItemEventTrackers
/v1/tenants/{tenant_id}/line-items/{line_item_id}/event-trackers

Replace the full set of a line item's event trackers.

parameters/TenantIdparameters/LineItemIdparameters/IdempotencyKeyschemas/EventTrackerSetschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/EventTrackerSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPlacementEventTrackers
/v1/tenants/{tenant_id}/placements/{placement_id}/event-trackers

List a placement's third-party event trackers (supply-side measurement).

parameters/TenantIdparameters/PlacementIdparameters/Limitparameters/Cursorschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The placement's trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replacePlacementEventTrackers
/v1/tenants/{tenant_id}/placements/{placement_id}/event-trackers

Replace the full set of a placement's event trackers.

parameters/TenantIdparameters/PlacementIdparameters/IdempotencyKeyschemas/EventTrackerSetschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PlacementId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/EventTrackerSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPublisherEventTrackers
/v1/tenants/{tenant_id}/publishers/{publisher_id}/event-trackers

List a publisher's third-party event trackers (default for all its placements).

parameters/TenantIdparameters/PublisherIdparameters/Limitparameters/Cursorschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The publisher's trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replacePublisherEventTrackers
/v1/tenants/{tenant_id}/publishers/{publisher_id}/event-trackers

Replace the full set of a publisher's event trackers.

parameters/TenantIdparameters/PublisherIdparameters/IdempotencyKeyschemas/EventTrackerSetschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/EventTrackerSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDealEventTrackers
/v1/tenants/{tenant_id}/deals/{deal_id}/event-trackers

List a deal's agreed third-party event trackers.

parameters/TenantIdparameters/DealIdparameters/Limitparameters/Cursorschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DealId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The deal's trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replaceDealEventTrackers
/v1/tenants/{tenant_id}/deals/{deal_id}/event-trackers

Replace the full set of a deal's event trackers.

parameters/TenantIdparameters/DealIdparameters/IdempotencyKeyschemas/EventTrackerSetschemas/EventTrackerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DealId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/EventTrackerSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored trackers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EventTrackerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getIvtPolicy
/v1/tenants/{tenant_id}/ivt-policy

Read the tenant's invalid-traffic detection and enforcement policy. Returns the platform defaults when no policy is stored.

schemas/IvtPolicyresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "The effective policy.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IvtPolicy"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateIvtPolicy
/v1/tenants/{tenant_id}/ivt-policy

Create or replace the tenant's IVT policy (one per tenant; upsert).

parameters/TenantIdparameters/IdempotencyKeyschemas/IvtPolicyUpdateschemas/IvtPolicyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/IvtPolicyUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored policy.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IvtPolicy"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
DELETE deleteIvtPolicy
/v1/tenants/{tenant_id}/ivt-policy

Delete the tenant's stored invalid-traffic policy and restore the platform defaults.

parameters/TenantIdparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Deleted."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listSupplyScorecards
/v1/tenants/{tenant_id}/supply-scorecards

List computed supply scorecards, including invalid-traffic rate and grade for each publisher and domain or app bundle.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/SupplyScorecardListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of scorecards.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SupplyScorecardList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listIpLists
/v1/tenants/{tenant_id}/ip-lists

List reusable IP allow or block lists for line-item targeting. This operation returns list metadata; membership data is held in object storage.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/IpListPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of IP lists.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IpListPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createIpList
/v1/tenants/{tenant_id}/ip-lists

Create an IP allow/block list (metadata only; import entries then publish). scope=cell is operator-only (cell-wide edge shed). scope=publisher requires a publisher_id owned by the tenant.

parameters/TenantIdparameters/IdempotencyKeyschemas/IpListCreateschemas/IpListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/IpListCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IpList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getIpList
/v1/tenants/{tenant_id}/ip-lists/{list_id}

Get one IP list's metadata (uri/hash/version/entry_count/status).

schemas/IpListresponses/Errorparameters/TenantIdparameters/IpListId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IpListId"
    }
  ],
  "responses": {
    "200": {
      "description": "The IP list.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IpList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveIpList
/v1/tenants/{tenant_id}/ip-lists/{list_id}/archive

Archive an IP list. Archived lists drop out of plan compile and reject further import/publish.

parameters/TenantIdparameters/IpListIdparameters/IdempotencyKeyschemas/IpListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IpListId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IpList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST bulkImportIpListEntries
/v1/tenants/{tenant_id}/ip-lists/{list_id}/entries:bulkImport

Import up to 10000 IP or CIDR lines into staging per call. A list can contain at most 2000000 staged lines before publication. Publishing compiles the staged entries into a membership file and clears staging.

parameters/TenantIdparameters/IpListIdparameters/IdempotencyKeyschemas/IpListBulkImportRequestschemas/IpListBulkImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IpListId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/IpListBulkImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Import accepted (accepted/rejected counts).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IpListBulkImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST publishIpList
/v1/tenants/{tenant_id}/ip-lists/{list_id}/publish

Compile staged IP/CIDR lines into a binary membership blob, write it to object storage, bump version/content_hash, and clear staging so the next plan compile projects IpListRef. Rejects empty allow-mode lists (would deny all traffic) and archived lists.

parameters/TenantIdparameters/IpListIdparameters/IdempotencyKeyschemas/IpListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IpListId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Published list metadata.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/IpList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listBidModifiers
/v1/tenants/{tenant_id}/bid-modifiers

List sets of bid multipliers that line items can reference through bid_modifier_id. The multipliers are included in the serving plan.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/BidModifierPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of bid modifiers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BidModifierPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createBidModifier
/v1/tenants/{tenant_id}/bid-modifiers

Create a bid modifier (metadata + optional initial terms; max 1000 terms).

parameters/TenantIdparameters/IdempotencyKeyschemas/BidModifierCreateschemas/BidModifierresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/BidModifierCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BidModifier"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getBidModifier
/v1/tenants/{tenant_id}/bid-modifiers/{modifier_id}

Get one bid modifier including its terms.

schemas/BidModifierresponses/Errorparameters/TenantIdparameters/BidModifierId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/BidModifierId"
    }
  ],
  "responses": {
    "200": {
      "description": "The bid modifier.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BidModifier"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateBidModifier
/v1/tenants/{tenant_id}/bid-modifiers/{modifier_id}

Update bid modifier metadata (name/description/active). Terms via replaceBidModifierTerms.

parameters/TenantIdparameters/BidModifierIdparameters/IdempotencyKeyschemas/BidModifierUpdateschemas/BidModifierresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/BidModifierId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/BidModifierUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BidModifier"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveBidModifier
/v1/tenants/{tenant_id}/bid-modifiers/{modifier_id}/archive

Archive a bid modifier. Archived modifiers drop out of plan compile and reject further term edits; line items referencing them keep the FK until cleared.

parameters/TenantIdparameters/BidModifierIdparameters/IdempotencyKeyschemas/BidModifierresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/BidModifierId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BidModifier"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replaceBidModifierTerms
/v1/tenants/{tenant_id}/bid-modifiers/{modifier_id}/terms

Replace-all bid modifier terms (max 1000). Matching multipliers multiply at apply time; clamp [0,10]; 0 ⇒ no-bid.

parameters/TenantIdparameters/BidModifierIdparameters/IdempotencyKeyschemas/BidModifierTermsReplaceschemas/BidModifierresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/BidModifierId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/BidModifierTermsReplace"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated modifier with the new term set.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BidModifier"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCustomLists
/v1/tenants/{tenant_id}/custom-lists

List custom targeting lists whose membership is included in the serving plan. Each list supports up to 10000 items.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/CustomListPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of custom lists.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CustomListPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createCustomList
/v1/tenants/{tenant_id}/custom-lists

Create a custom list (metadata + optional initial items; max 10000 items).

parameters/TenantIdparameters/IdempotencyKeyschemas/CustomListCreateschemas/CustomListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CustomListCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created custom list.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CustomList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCustomList
/v1/tenants/{tenant_id}/custom-lists/{list_id}

Get one custom list including its items.

schemas/CustomListresponses/Errorparameters/TenantIdparameters/CustomListId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CustomListId"
    }
  ],
  "responses": {
    "200": {
      "description": "The custom list.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CustomList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateCustomList
/v1/tenants/{tenant_id}/custom-lists/{list_id}

Update custom list metadata (name). Items via replaceCustomListItems.

parameters/TenantIdparameters/CustomListIdparameters/IdempotencyKeyschemas/CustomListUpdateschemas/CustomListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CustomListId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CustomListUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated custom list.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CustomList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveCustomList
/v1/tenants/{tenant_id}/custom-lists/{list_id}/archive

Archive a custom list. Archived lists drop out of plan compile.

parameters/TenantIdparameters/CustomListIdparameters/IdempotencyKeyschemas/CustomListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CustomListId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived custom list.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CustomList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replaceCustomListItems
/v1/tenants/{tenant_id}/custom-lists/{list_id}/items

Replace-all custom list items (max 10000). Values are normalized (trim + lower for domain/site/app_bundle/zip).

parameters/TenantIdparameters/CustomListIdparameters/IdempotencyKeyschemas/CustomListItemsReplaceschemas/CustomListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CustomListId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CustomListItemsReplace"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated list with the new item set.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CustomList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCreativeTemplates
/v1/tenants/{tenant_id}/creative-templates

List creative templates. The markup_template uses {{MACRO}} substitution; creatives reference a template through template_id and template_fields.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/CreativeTemplatePageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of creative templates.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeTemplatePage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createCreativeTemplate
/v1/tenants/{tenant_id}/creative-templates

Create a creative template.

parameters/TenantIdparameters/IdempotencyKeyschemas/CreativeTemplateCreateschemas/CreativeTemplateresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreativeTemplateCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created creative template.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeTemplate"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCreativeTemplate
/v1/tenants/{tenant_id}/creative-templates/{template_id}

Get one creative template.

schemas/CreativeTemplateresponses/Errorparameters/TenantIdparameters/CreativeTemplateId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeTemplateId"
    }
  ],
  "responses": {
    "200": {
      "description": "The creative template.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeTemplate"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateCreativeTemplate
/v1/tenants/{tenant_id}/creative-templates/{template_id}

Update a creative template.

parameters/TenantIdparameters/CreativeTemplateIdparameters/IdempotencyKeyschemas/CreativeTemplateUpdateschemas/CreativeTemplateresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeTemplateId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreativeTemplateUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated creative template.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeTemplate"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveCreativeTemplate
/v1/tenants/{tenant_id}/creative-templates/{template_id}/archive

Archive a creative template. Archived templates drop out of plan compile.

parameters/TenantIdparameters/CreativeTemplateIdparameters/IdempotencyKeyschemas/CreativeTemplateresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeTemplateId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived creative template.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeTemplate"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST refreshCreativeTemplate
/v1/tenants/{tenant_id}/creative-templates/{template_id}/refresh

Start refreshing a template's dynamic creatives from its refresh_source_url. The platform fetches the feed and regenerates variants for creatives using the template. Returns 202 with a RUNNING progress record; refresh_status and last_refreshed_at track the result. Returns 409 CONFLICT if a run is already active, or BAD_INPUT if refresh_source_url is missing. Requires campaign.write.

parameters/TenantIdparameters/CreativeTemplateIdparameters/IdempotencyKeyschemas/CreativeTemplateRefreshRunresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeTemplateId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "202": {
      "description": "The refresh run that was started.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeTemplateRefreshRun"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDeliveryExperiments
/v1/tenants/{tenant_id}/delivery-experiments

List delivery experiments with stable user holdout assignments. The control group suppresses subjects assigned to TREATMENT.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/DeliveryExperimentPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of delivery experiments.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryExperimentPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createDeliveryExperiment
/v1/tenants/{tenant_id}/delivery-experiments

Create a delivery experiment (metadata + optional subjects).

parameters/TenantIdparameters/IdempotencyKeyschemas/DeliveryExperimentCreateschemas/DeliveryExperimentresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeliveryExperimentCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created delivery experiment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryExperiment"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDeliveryExperiment
/v1/tenants/{tenant_id}/delivery-experiments/{experiment_id}

Get one delivery experiment including subjects.

schemas/DeliveryExperimentresponses/Errorparameters/TenantIdparameters/DeliveryExperimentId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryExperimentId"
    }
  ],
  "responses": {
    "200": {
      "description": "The delivery experiment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryExperiment"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateDeliveryExperiment
/v1/tenants/{tenant_id}/delivery-experiments/{experiment_id}

Update delivery experiment metadata (name, holdout_pct, description).

parameters/TenantIdparameters/DeliveryExperimentIdparameters/IdempotencyKeyschemas/DeliveryExperimentUpdateschemas/DeliveryExperimentresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryExperimentId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeliveryExperimentUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated delivery experiment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryExperiment"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveDeliveryExperiment
/v1/tenants/{tenant_id}/delivery-experiments/{experiment_id}/archive

Archive a delivery experiment. Archived experiments drop out of plan compile.

parameters/TenantIdparameters/DeliveryExperimentIdparameters/IdempotencyKeyschemas/DeliveryExperimentresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryExperimentId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived delivery experiment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryExperiment"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT replaceDeliveryExperimentSubjects
/v1/tenants/{tenant_id}/delivery-experiments/{experiment_id}/subjects

Replace-all experiment subjects (campaign orders and/or line items + arm).

parameters/TenantIdparameters/DeliveryExperimentIdparameters/IdempotencyKeyschemas/DeliveryExperimentSubjectsReplaceschemas/DeliveryExperimentresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryExperimentId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeliveryExperimentSubjectsReplace"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated experiment with the new subject set.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryExperiment"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDeliveryAlertRules
/v1/tenants/{tenant_id}/delivery-alert-rules

List delivery and spending alert rules. The evaluator fires an alert when a threshold is crossed and sends a webhook when one is configured.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/DeliveryAlertRulePageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of delivery alert rules.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertRulePage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createDeliveryAlertRule
/v1/tenants/{tenant_id}/delivery-alert-rules

Create a delivery alert rule.

parameters/TenantIdparameters/IdempotencyKeyschemas/DeliveryAlertRuleCreateschemas/DeliveryAlertRuleCreatedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeliveryAlertRuleCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created delivery alert rule (webhook_secret_ref echoed when set; secret never returned).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertRuleCreated"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDeliveryAlertRule
/v1/tenants/{tenant_id}/delivery-alert-rules/{rule_id}

Read a delivery alert rule. The webhook secret is excluded from the response.

schemas/DeliveryAlertRuleresponses/Errorparameters/TenantIdparameters/DeliveryAlertRuleId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryAlertRuleId"
    }
  ],
  "responses": {
    "200": {
      "description": "The delivery alert rule.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertRule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateDeliveryAlertRule
/v1/tenants/{tenant_id}/delivery-alert-rules/{rule_id}

Update a delivery alert rule. Omit webhook_secret_ref to leave unchanged.

parameters/TenantIdparameters/DeliveryAlertRuleIdparameters/IdempotencyKeyschemas/DeliveryAlertRuleUpdateschemas/DeliveryAlertRuleresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryAlertRuleId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeliveryAlertRuleUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated delivery alert rule.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertRule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveDeliveryAlertRule
/v1/tenants/{tenant_id}/delivery-alert-rules/{rule_id}/archive

Archive a delivery alert rule (disabled for evaluation).

parameters/TenantIdparameters/DeliveryAlertRuleIdparameters/IdempotencyKeyschemas/DeliveryAlertRuleresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryAlertRuleId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived delivery alert rule.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertRule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST muteDeliveryAlertRule
/v1/tenants/{tenant_id}/delivery-alert-rules/{rule_id}/mute

Mute or unmute a delivery alert rule until a specified time. Muted rules are evaluated but do not fire alerts.

parameters/TenantIdparameters/DeliveryAlertRuleIdparameters/IdempotencyKeyschemas/DeliveryAlertMuteRequestschemas/DeliveryAlertRuleresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryAlertRuleId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeliveryAlertMuteRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The rule with its new muted_until.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertRule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST acknowledgeDeliveryAlertEvent
/v1/tenants/{tenant_id}/delivery-alert-events/{event_id}/acknowledge

Acknowledge an alert firing (records who and when; idempotent on an already-acknowledged event).

parameters/TenantIdparameters/DeliveryAlertEventIdparameters/IdempotencyKeyschemas/DeliveryAlertEventresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DeliveryAlertEventId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "The acknowledged event.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertEvent"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDeliveryAlertEvents
/v1/tenants/{tenant_id}/delivery-alert-events

List recent delivery alert firings (newest first).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/DeliveryAlertEventPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "rule_id",
      "in": "query",
      "schema": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Optional filter to one rule."
    }
  ],
  "responses": {
    "200": {
      "description": "A page of alert events.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryAlertEventPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listItemCatalogs
/v1/tenants/{tenant_id}/item-catalogs

List product and SKU catalogs used for onsite listing auctions and product attribution. These are separate from marketplace listings.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ItemCatalogPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of item catalogs.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ItemCatalogPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createItemCatalog
/v1/tenants/{tenant_id}/item-catalogs

Create an item catalog container.

parameters/TenantIdparameters/IdempotencyKeyschemas/ItemCatalogCreateschemas/ItemCatalogresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ItemCatalogCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created item catalog.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ItemCatalog"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getItemCatalog
/v1/tenants/{tenant_id}/item-catalogs/{catalog_id}

Get one item catalog.

schemas/ItemCatalogresponses/Errorparameters/TenantIdparameters/ItemCatalogId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ItemCatalogId"
    }
  ],
  "responses": {
    "200": {
      "description": "The item catalog.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ItemCatalog"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateItemCatalog
/v1/tenants/{tenant_id}/item-catalogs/{catalog_id}

Update item catalog metadata.

parameters/TenantIdparameters/ItemCatalogIdparameters/IdempotencyKeyschemas/ItemCatalogUpdateschemas/ItemCatalogresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ItemCatalogId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ItemCatalogUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated item catalog.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ItemCatalog"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveItemCatalog
/v1/tenants/{tenant_id}/item-catalogs/{catalog_id}/archive

Archive an item catalog (soft; items remain for attribution history).

parameters/TenantIdparameters/ItemCatalogIdparameters/IdempotencyKeyschemas/ItemCatalogresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ItemCatalogId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived item catalog.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ItemCatalog"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCatalogItems
/v1/tenants/{tenant_id}/item-catalogs/{catalog_id}/items

List catalog items (SKU/product rows) in an item catalog.

parameters/TenantIdparameters/ItemCatalogIdparameters/Limitparameters/Cursorschemas/CatalogItemPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ItemCatalogId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of catalog items.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CatalogItemPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT upsertCatalogItems
/v1/tenants/{tenant_id}/item-catalogs/{catalog_id}/items

Bulk upsert catalog items by external_item_id (idempotent on tenant+catalog+external_item_id). Max 1000 items per call.

parameters/TenantIdparameters/ItemCatalogIdparameters/IdempotencyKeyschemas/CatalogItemUpsertschemas/CatalogItemPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ItemCatalogId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CatalogItemUpsert"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Upserted items (full rows after write).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CatalogItemPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listExportDestinations
/v1/tenants/{tenant_id}/export-destinations

List the tenant's S3 and GCS event-export destinations. Credentials are stored in the secret store and referenced by secret_ref.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ExportDestinationPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of export destinations.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportDestinationPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createExportDestination
/v1/tenants/{tenant_id}/export-destinations

Create an export destination (S3 or GCS).

parameters/TenantIdparameters/IdempotencyKeyschemas/ExportDestinationCreateschemas/ExportDestinationresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ExportDestinationCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created export destination.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportDestination"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getExportDestination
/v1/tenants/{tenant_id}/export-destinations/{destination_id}

Get one export destination.

schemas/ExportDestinationresponses/Errorparameters/TenantIdparameters/ExportDestinationId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ExportDestinationId"
    }
  ],
  "responses": {
    "200": {
      "description": "The export destination.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportDestination"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateExportDestination
/v1/tenants/{tenant_id}/export-destinations/{destination_id}

Update an export destination.

parameters/TenantIdparameters/ExportDestinationIdparameters/IdempotencyKeyschemas/ExportDestinationUpdateschemas/ExportDestinationresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ExportDestinationId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ExportDestinationUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated export destination.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportDestination"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveExportDestination
/v1/tenants/{tenant_id}/export-destinations/{destination_id}/archive

Archive an export destination (stops future export ticks).

parameters/TenantIdparameters/ExportDestinationIdparameters/IdempotencyKeyschemas/ExportDestinationresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ExportDestinationId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived export destination.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportDestination"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listExportJobs
/v1/tenants/{tenant_id}/export-jobs

List on-demand customer log export jobs. For continuous exports, use event-export destinations.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ExportJobPageresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of export jobs.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportJobPage"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createExportJob
/v1/tenants/{tenant_id}/export-jobs

Request a customer log export for one event kind and time range. A background job writes JSONL or CSV to object storage and sets blob_uri when the export is available.

parameters/TenantIdparameters/IdempotencyKeyschemas/ExportJobCreateschemas/ExportJobresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ExportJobCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created export job (PENDING until the tick completes).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportJob"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getExportJob
/v1/tenants/{tenant_id}/export-jobs/{job_id}

Get one export job (status, blob_uri, row_count).

schemas/ExportJobresponses/Errorparameters/TenantIdparameters/ExportJobId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ExportJobId"
    }
  ],
  "responses": {
    "200": {
      "description": "The export job.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportJob"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveExportJob
/v1/tenants/{tenant_id}/export-jobs/{job_id}/archive

Archive an export job (soft; blob may be retained by retention policy).

parameters/TenantIdparameters/ExportJobIdparameters/IdempotencyKeyschemas/ExportJobresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ExportJobId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived export job.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExportJob"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getTenantOIDCConfig
/v1/tenants/{tenant_id}/oidc-config

Read the tenant's OIDC single sign-on configuration. Secrets are referenced through secret_ref.

schemas/TenantOIDCConfigresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "OIDC config (defaults when unset).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantOIDCConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateTenantOIDCConfig
/v1/tenants/{tenant_id}/oidc-config

Upsert tenant OIDC SSO config (one row per tenant in v1).

parameters/TenantIdparameters/IdempotencyKeyschemas/TenantOIDCConfigUpdateschemas/TenantOIDCConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TenantOIDCConfigUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated OIDC config.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantOIDCConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getTenantSAMLConfig
/v1/tenants/{tenant_id}/saml-config

Read the tenant's SAML single sign-on configuration. The identity-provider certificate is referenced through cert_ref in the secret store.

schemas/TenantSAMLConfigresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "SAML config (defaults when unset).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantSAMLConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateTenantSAMLConfig
/v1/tenants/{tenant_id}/saml-config

Upsert tenant SAML SSO config (one row per tenant in v1).

parameters/TenantIdparameters/IdempotencyKeyschemas/TenantSAMLConfigUpdateschemas/TenantSAMLConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TenantSAMLConfigUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated SAML config.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantSAMLConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listSealingKeys
/v1/tenants/{tenant_id}/sealing-keys

List metadata for a tenant's sealing keys. Key material is excluded.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/SealingKeyListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of sealing keys.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SealingKeyList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createSealingKey
/v1/tenants/{tenant_id}/sealing-keys

Create and activate a sealing key, retiring the tenant's previous ACTIVE key. The response contains metadata only; ciphertext and raw key material are excluded.

parameters/TenantIdparameters/IdempotencyKeyschemas/SealingKeyCreateschemas/SealingKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/SealingKeyCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created and activated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SealingKey"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST retireSealingKey
/v1/tenants/{tenant_id}/sealing-keys/{key_id}/retire

Retire a sealing key by its opaque key id (metadata response only).

parameters/TenantIdparameters/SealingKeyIdparameters/IdempotencyKeyschemas/SealingKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/SealingKeyId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Retired.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SealingKey"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDemandPartners
/v1/tenants/{tenant_id}/demand-partners

List a tenant's demand partners.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/DemandPartnerListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of demand partners.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandPartnerList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createDemandPartner
/v1/tenants/{tenant_id}/demand-partners

Create a demand partner.

parameters/TenantIdparameters/IdempotencyKeyschemas/DemandPartnerCreateschemas/DemandPartnerresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DemandPartnerCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandPartner"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST bulkImportDemandPartners
/v1/tenants/{tenant_id}/demand-partners/bulk-import

Create demand partners in a batch and return a result for each row. A failed row does not abort other rows. With dry_run: true, validate required fields and name conflicts both inside the batch and against stored partners without saving changes.

parameters/TenantIdparameters/IdempotencyKeyschemas/DemandPartnerBulkImportRequestschemas/DemandPartnerBulkImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DemandPartnerBulkImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row results (dry-run preview or applied).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandPartnerBulkImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDemandPartner
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}

Get a demand partner.

schemas/DemandPartnerresponses/Errorparameters/TenantIdparameters/DemandPartnerId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    }
  ],
  "responses": {
    "200": {
      "description": "The demand partner.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandPartner"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateDemandPartner
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}

Update a demand partner's name and/or default buyer notice TTL.

parameters/TenantIdparameters/DemandPartnerIdparameters/IdempotencyKeyschemas/DemandPartnerUpdateschemas/DemandPartnerresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DemandPartnerUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandPartner"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveDemandPartner
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/archive

Archive a demand partner.

parameters/TenantIdparameters/DemandPartnerIdparameters/IdempotencyKeyschemas/DemandPartnerresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandPartner"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDemandPartnerStatusCounts
/v1/tenants/{tenant_id}/demand-partners/status-counts

Per-status row counts for the tenant's demand partners.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDemandRoutes
/v1/tenants/{tenant_id}/demand-routes

List a tenant's demand routes.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/DemandRouteListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "demand_partner_id",
      "in": "query",
      "required": false,
      "description": "Restrict the list to routes owned by this partner.",
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of demand routes.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandRouteList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createDemandRoute
/v1/tenants/{tenant_id}/demand-routes

Create a demand route with endpoints, seats, deals, parameters, fanout, and audience settings. Configure request rewrites through the separate rewrite endpoints.

parameters/TenantIdparameters/IdempotencyKeyschemas/DemandRouteCreateschemas/DemandRouteresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DemandRouteCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandRoute"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDemandRoute
/v1/tenants/{tenant_id}/demand-routes/{demand_route_id}

Get a demand route.

schemas/DemandRouteresponses/Errorparameters/TenantIdparameters/DemandRouteId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandRouteId"
    }
  ],
  "responses": {
    "200": {
      "description": "The demand route.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandRoute"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateDemandRoute
/v1/tenants/{tenant_id}/demand-routes/{demand_route_id}

Update a demand route. demand_partner_id and integration are immutable after creation (create a new route to change either).

parameters/TenantIdparameters/DemandRouteIdparameters/IdempotencyKeyschemas/DemandRouteUpdateschemas/DemandRouteresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandRouteId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DemandRouteUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandRoute"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveDemandRoute
/v1/tenants/{tenant_id}/demand-routes/{demand_route_id}/archive

Archive a demand route.

parameters/TenantIdparameters/DemandRouteIdparameters/IdempotencyKeyschemas/DemandRouteresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandRouteId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandRoute"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDemandRouteRewrites
/v1/tenants/{tenant_id}/demand-routes/{demand_route_id}/rewrites

List a demand route's request-rewrite rules.

parameters/TenantIdparameters/DemandRouteIdparameters/Limitparameters/Cursorschemas/RouteRewriteListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandRouteId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The route's rewrite rules.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/RouteRewriteList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT setDemandRouteRewrites
/v1/tenants/{tenant_id}/demand-routes/{demand_route_id}/rewrites

Replace a demand route's full rewrite rule set (validated: path is required; a clearing rule must not also carry a value; a rule is not both overwrite and clear).

parameters/TenantIdparameters/DemandRouteIdparameters/IdempotencyKeyschemas/RouteRewriteSetschemas/RouteRewriteListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandRouteId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/RouteRewriteSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The route's rewrite rules after the replace.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/RouteRewriteList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST previewDemandRouteRewrites
/v1/tenants/{tenant_id}/demand-routes/{demand_route_id}/rewrites/preview

Preview a route's request rewrites against a supplied OpenRTB bid request using the same rules as outbound demand requests. Returns the original request, rewritten request, and applied rules without saving changes.

schemas/DemandRouteRewritePreviewRequestschemas/DemandRouteRewritePreviewResponseresponses/Errorparameters/TenantIdparameters/DemandRouteId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandRouteId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DemandRouteRewritePreviewRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Before/after bid request preview.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandRouteRewritePreviewResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST cloneDemandRoute
/v1/tenants/{tenant_id}/demand-routes/{demand_route_id}/clone

Create a new ACTIVE demand route with all configuration fields and rewrite rules copied from the source route.

parameters/TenantIdparameters/DemandRouteIdparameters/IdempotencyKeyschemas/DemandRouteresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandRouteId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "201": {
      "description": "The cloned route.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DemandRoute"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDemandRouteStatusCounts
/v1/tenants/{tenant_id}/demand-routes/status-counts

Per-status row counts for the tenant's demand routes.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDeals
/v1/tenants/{tenant_id}/deals

List a tenant's deals.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/DealListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "advertiser_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Only deals associated with this advertiser (Deal.advertiser_id)."
    }
  ],
  "responses": {
    "200": {
      "description": "A page of deals.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DealList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createDeal
/v1/tenants/{tenant_id}/deals

Create a deal with seats, advertiser domains, verification, audience settings, and per-deal frequency caps.

parameters/TenantIdparameters/IdempotencyKeyschemas/DealCreateschemas/Dealresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DealCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Deal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDeal
/v1/tenants/{tenant_id}/deals/{deal_id}

Get a deal.

schemas/Dealresponses/Errorparameters/TenantIdparameters/DealId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DealId"
    }
  ],
  "responses": {
    "200": {
      "description": "The deal.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Deal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateDeal
/v1/tenants/{tenant_id}/deals/{deal_id}

Update a deal. external_id is immutable after creation.

parameters/TenantIdparameters/DealIdparameters/IdempotencyKeyschemas/DealUpdateschemas/Dealresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DealId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DealUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Deal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST pushDeal
/v1/tenants/{tenant_id}/deals/{deal_id}/push

Send a deal's terms to a demand partner's deal endpoint. The response tracks delivery through PENDING, SENT, and ACKNOWLEDGED, or FAILED with the partner's error. Returns 202 while delivery continues. Repeated pushes of unchanged terms are deduplicated by their payload hash.

parameters/TenantIdparameters/DealIdparameters/IdempotencyKeyschemas/DealPushRequestschemas/DealSyncresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DealId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DealPushRequest"
        }
      }
    }
  },
  "responses": {
    "202": {
      "description": "The deal_sync row tracking the push.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DealSync"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveDeal
/v1/tenants/{tenant_id}/deals/{deal_id}/archive

Archive a deal.

parameters/TenantIdparameters/DealIdparameters/IdempotencyKeyschemas/Dealresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DealId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Deal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDealMakegood
/v1/tenants/{tenant_id}/deals/{deal_id}/makegood

Recommend a makegood for a guaranteed deal with a delivery commitment. The calculation compares the deal's delivery counters, commitment, and flight, then reports on_track, behind, delivered, or shortfall and the amount needed to cover a shortfall. This recommendation changes neither money nor counters. Returns 404 for an unknown deal or 409 CONFLICT when the deal lacks guaranteed=true and either committed_impressions or committed_spend.

schemas/DealMakegoodRecommendationresponses/Errorparameters/TenantIdparameters/DealId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DealId"
    }
  ],
  "responses": {
    "200": {
      "description": "The computed recommendation.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DealMakegoodRecommendation"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST receiveDeal
/v1/deals/inbound

Receive a partner's deal using a partner-scoped API key created by the receiving tenant. The key determines the tenant. The deal is created under the partner's external_ref; subsequent pushes with the same reference update it. A sync record stores the payload hash. Returns 202 while processing continues.

parameters/IdempotencyKeyschemas/DealInboundRequestschemas/DealSyncresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DealInboundRequest"
        }
      }
    }
  },
  "responses": {
    "202": {
      "description": "The deal_sync row recording the inbound deal.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DealSync"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDealStatusCounts
/v1/tenants/{tenant_id}/deals/status-counts

Per-status row counts for the tenant's deals.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listMarketplaces
/v1/tenants/{tenant_id}/marketplaces

List a tenant's marketplaces (packaged demand-route bundles).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/MarketplaceListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of marketplaces.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createMarketplace
/v1/tenants/{tenant_id}/marketplaces

Create a marketplace.

parameters/TenantIdparameters/IdempotencyKeyschemas/MarketplaceCreateschemas/Marketplaceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/MarketplaceCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Marketplace"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getMarketplace
/v1/tenants/{tenant_id}/marketplaces/{marketplace_id}

Get a marketplace.

schemas/Marketplaceresponses/Errorparameters/TenantIdparameters/MarketplaceId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceId"
    }
  ],
  "responses": {
    "200": {
      "description": "The marketplace.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Marketplace"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateMarketplace
/v1/tenants/{tenant_id}/marketplaces/{marketplace_id}

Update a marketplace's name and/or rev share. code is immutable after creation.

parameters/TenantIdparameters/MarketplaceIdparameters/IdempotencyKeyschemas/MarketplaceUpdateschemas/Marketplaceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/MarketplaceUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Marketplace"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listMarketplaceDeals
/v1/tenants/{tenant_id}/marketplaces/{marketplace_id}/deals

List the deal IDs packaged by a marketplace.

parameters/TenantIdparameters/MarketplaceIdparameters/Limitparameters/Cursorschemas/MarketplaceDealMembershipresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The marketplace's packaged deal membership.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceDealMembership"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT setMarketplaceDeals
/v1/tenants/{tenant_id}/marketplaces/{marketplace_id}/deals

Replace a marketplace's full packaged deal set.

parameters/TenantIdparameters/MarketplaceIdparameters/IdempotencyKeyschemas/MarketplaceDealMembershipresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/MarketplaceDealMembership"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated packaged deal membership.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceDealMembership"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveMarketplace
/v1/tenants/{tenant_id}/marketplaces/{marketplace_id}/archive

Archive a marketplace.

parameters/TenantIdparameters/MarketplaceIdparameters/IdempotencyKeyschemas/Marketplaceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Marketplace"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getMarketplaceStatusCounts
/v1/tenants/{tenant_id}/marketplaces/status-counts

Per-status row counts for the tenant's marketplaces.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listMarketplaceListings
/v1/tenants/{tenant_id}/marketplace-listings

List seller-owned marketplace listings (discovery packages).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/MarketplaceListingListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of marketplace listings.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListingList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createMarketplaceListing
/v1/tenants/{tenant_id}/marketplace-listings

Create a DRAFT marketplace listing.

parameters/TenantIdparameters/IdempotencyKeyschemas/MarketplaceListingCreateschemas/MarketplaceListingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/MarketplaceListingCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListing"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getMarketplaceListing
/v1/tenants/{tenant_id}/marketplace-listings/{listing_id}

Get a seller-owned marketplace listing.

schemas/MarketplaceListingresponses/Errorparameters/TenantIdparameters/MarketplaceListingId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceListingId"
    }
  ],
  "responses": {
    "200": {
      "description": "The listing.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListing"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateMarketplaceListing
/v1/tenants/{tenant_id}/marketplace-listings/{listing_id}

Update a marketplace listing. Code is immutable. Updating a PUBLISHED listing reverts it to DRAFT and clears terms_summary (must re-publish).

parameters/TenantIdparameters/MarketplaceListingIdparameters/IdempotencyKeyschemas/MarketplaceListingUpdateschemas/MarketplaceListingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceListingId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/MarketplaceListingUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListing"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST publishMarketplaceListing
/v1/tenants/{tenant_id}/marketplace-listings/{listing_id}/publish

Publish a listing (DRAFT/PAUSED → PUBLISHED), compute and persist terms_summary. FEDERATED visibility requires the open_marketplace entitlement.

parameters/TenantIdparameters/MarketplaceListingIdparameters/IdempotencyKeyschemas/MarketplaceListingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceListingId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Published.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListing"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST publishStackProduct
/v1/tenants/{tenant_id}/marketplace-listings/{listing_id}/stack-product/publish

Publish a STACK_PRODUCT listing (vendor entitlement + verified conformance required).

parameters/TenantIdparameters/MarketplaceListingIdparameters/IdempotencyKeyschemas/MarketplaceListingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceListingId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Published stack product.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListing"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST installStackProduct
/v1/tenants/{tenant_id}/stack-products/install

Install a published stack product (INSTALL_STACK_PRODUCT activation).

parameters/TenantIdparameters/IdempotencyKeyschemas/StackProductInstallRequestschemas/ListingActivationresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/StackProductInstallRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Installed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingActivation"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST uninstallStackProduct
/v1/tenants/{tenant_id}/stack-products/activations/{activation_id}/uninstall

Revoke a stack-product install (uninstall).

parameters/TenantIdparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "activation_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Uninstalled."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listTenantExtensions
/v1/tenants/{tenant_id}/tenant-extensions

List the tenant's installed extensions with their kind, listing reference, and execution budgets. This read-only response excludes capability tokens and connection secrets.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/TenantExtensionListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "extension_kind",
      "in": "query",
      "required": false,
      "description": "Optional filter (e.g. BID_SOURCE). Open enum — unknown values return an empty page. REPORT_FIELD and DECISIONER are retired kinds (ADR D57): no listing carries them and filtering on either returns an empty page.\n",
      "schema": {
        "type": "string",
        "enum": [
          "BID_SOURCE",
          "DEMAND_ADAPTER",
          "ENRICHER",
          "AUDIENCE_EVALUATOR",
          "PRICING_MODULE",
          "CREATIVE_RENDERER",
          "VERIFICATION_VENDOR",
          "REPORT_FIELD",
          "DECISIONER",
          "DEMAND_ATTACHMENT"
        ]
      }
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of installed tenant extensions.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantExtensionList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runExtensionConformance
/v1/operator/stack-products/conformance-runs

Record an operator-verified passing result for extension conformance. This operation records evidence; it does not execute the conformance tests. Operator access required.

parameters/IdempotencyKeyschemas/RunExtensionConformanceRequestschemas/ExtensionConformanceRunResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/RunExtensionConformanceRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Recorded conformance run.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ExtensionConformanceRunResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST pauseMarketplaceListing
/v1/tenants/{tenant_id}/marketplace-listings/{listing_id}/pause

Pause a PUBLISHED marketplace listing.

parameters/TenantIdparameters/MarketplaceListingIdparameters/IdempotencyKeyschemas/MarketplaceListingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceListingId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Paused.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListing"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDiscoverableMarketplaceListings
/v1/tenants/{tenant_id}/marketplace-discovery/listings

Discover available marketplace listings in the same tenant.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ListingKindschemas/MarketplaceListingListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "buyer_seat",
      "in": "query",
      "schema": {
        "type": "string"
      },
      "description": "Seat used for PRIVATE allowlist matching."
    },
    {
      "name": "media",
      "in": "query",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "kind",
      "in": "query",
      "schema": {
        "$ref": "#/components/schemas/ListingKind"
      }
    },
    {
      "name": "q",
      "in": "query",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "min_floor",
      "in": "query",
      "schema": {
        "type": "string",
        "description": "Decimal string informational floor filter."
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Discoverable listings page.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListingList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDiscoverableMarketplaceListing
/v1/tenants/{tenant_id}/marketplace-discovery/listings/{listing_id}

Read a discoverable listing with its terms summary and deal summaries.

parameters/TenantIdparameters/MarketplaceListingIdschemas/MarketplaceListingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/MarketplaceListingId"
    },
    {
      "name": "buyer_seat",
      "in": "query",
      "schema": {
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "The listing when visible to the seat.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceListing"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createPasteSiteDraft
/v1/tenants/{tenant_id}/paste-site

Create a default WEB placement and a PRIVATE SUPPLY_PACK draft for a publisher's site.

Does not grant entitlements. Idempotent via Idempotency-Key.

parameters/TenantIdparameters/IdempotencyKeyschemas/PasteSiteCreateschemas/PasteSiteResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PasteSiteCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Placement + draft listing created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PasteSiteResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPathReceipt
/v1/tenants/{tenant_id}/path-receipts/{fill_id}

Read the path receipt for a fill.

Returns the participants, fee lines, and deal context recorded for one fill. The same report is available through riptide.marketplace.get_path_receipt. A receipt is a reporting record, not a signed path attestation.

schemas/PathReceiptresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "fill_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string"
      },
      "description": "Fill / bid_uid identifying the receipt (design 25 §7)."
    }
  ],
  "responses": {
    "200": {
      "description": "Path receipt.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PathReceipt"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listListingActivations
/v1/tenants/{tenant_id}/listing-activations

List activations owned by the tenant (buyer binds).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ListingActivationListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "listing_id",
      "in": "query",
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Activation page.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingActivationList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createListingActivation
/v1/tenants/{tenant_id}/listing-activations

Activate a listing by merging its deals onto a demand route. Repeating the activation is idempotent.

parameters/TenantIdparameters/IdempotencyKeyschemas/ListingActivationCreateschemas/ListingActivationresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ListingActivationCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created (or existing idempotency match).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingActivation"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST revokeListingActivation
/v1/tenants/{tenant_id}/listing-activations/{activation_id}/revoke

Revoke an activation; deals drop on next plan compile.

parameters/TenantIdparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "activation_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Revoked (idempotent if already revoked)."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listListingProposals
/v1/tenants/{tenant_id}/listing-proposals

List proposals for which the tenant is the proposer or listing owner, newest first. Results use cursor pagination; status and role filters are applied before pagination.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ProposalStateschemas/ProposalPartyRoleschemas/ListingProposalListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Only threads whose current state equals this value.",
      "schema": {
        "$ref": "#/components/schemas/ProposalState"
      }
    },
    {
      "name": "role",
      "in": "query",
      "required": false,
      "description": "Only threads where the tenant holds this party role (PROPOSER = threads it opened; OWNER = threads opened against its listings).",
      "schema": {
        "$ref": "#/components/schemas/ProposalPartyRole"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of proposal threads (the caller's party rows).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingProposalList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST proposeListingTerms
/v1/tenants/{tenant_id}/listing-proposals

Create a listing proposal for negotiation between the proposer and listing owner.

parameters/TenantIdparameters/IdempotencyKeyschemas/ListingProposalCreateschemas/ListingProposalresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ListingProposalCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created proposal thread (caller party row).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingProposal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getListingProposal
/v1/tenants/{tenant_id}/listing-proposals/{thread_id}

Get this tenant's row for a proposal thread.

schemas/ListingProposalresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "thread_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Proposal row visible to the tenant.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingProposal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST counterListingProposal
/v1/tenants/{tenant_id}/listing-proposals/{thread_id}/counter

Counter proposal terms (revision CAS).

parameters/TenantIdparameters/IdempotencyKeyschemas/ListingProposalCounterschemas/ListingProposalresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "thread_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ListingProposalCounter"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated proposal row.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingProposal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST approveListingProposal
/v1/tenants/{tenant_id}/listing-proposals/{thread_id}/approve

Approve proposal and create listing activation atomically.

parameters/TenantIdparameters/IdempotencyKeyschemas/ListingProposalApproveschemas/ListingProposalApproveResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "thread_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ListingProposalApprove"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Approved proposal plus activation id when created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingProposalApproveResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST rejectListingProposal
/v1/tenants/{tenant_id}/listing-proposals/{thread_id}/reject

Reject the latest proposal revision (revision CAS).

parameters/TenantIdparameters/IdempotencyKeyschemas/ListingProposalMutateschemas/ListingProposalresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "thread_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ListingProposalMutate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Rejected proposal row.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingProposal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST withdrawListingProposal
/v1/tenants/{tenant_id}/listing-proposals/{thread_id}/withdraw

Withdraw proposal (proposer only; revision CAS).

parameters/TenantIdparameters/IdempotencyKeyschemas/ListingProposalMutateschemas/ListingProposalresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "thread_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ListingProposalMutate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Withdrawn proposal row.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ListingProposal"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCampaignOrders
/v1/tenants/{tenant_id}/campaign-orders

List a tenant's campaign orders (booked advertiser orders).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/CampaignOrderListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of campaign orders.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrderList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createCampaignOrder
/v1/tenants/{tenant_id}/campaign-orders

Create a campaign order.

parameters/TenantIdparameters/IdempotencyKeyschemas/CampaignOrderCreateschemas/CampaignOrderresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CampaignOrderCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrder"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST bulkImportCampaignOrders
/v1/tenants/{tenant_id}/campaign-orders/bulk-import

Create or update campaign orders by ref from a JSON array. Return a result for each row. With dry_run: true, validate without saving changes. Existing references are updated; new references create orders.

parameters/TenantIdparameters/IdempotencyKeyschemas/CampaignOrderBulkImportRequestschemas/CampaignOrderBulkImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CampaignOrderBulkImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row results (dry-run preview or applied upsert).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrderBulkImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCampaignOrder
/v1/tenants/{tenant_id}/campaign-orders/{campaign_order_id}

Get a campaign order.

schemas/CampaignOrderresponses/Errorparameters/TenantIdparameters/CampaignOrderId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CampaignOrderId"
    }
  ],
  "responses": {
    "200": {
      "description": "The campaign order.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrder"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateCampaignOrder
/v1/tenants/{tenant_id}/campaign-orders/{campaign_order_id}

Update a campaign order's name, delivery_status, flight, timezone, budgets, and frequency caps. The ref, advertiser_id, and currency are immutable. Pausing or ending an order prevents its line items from serving; archiving an order also archives its line items.

parameters/TenantIdparameters/CampaignOrderIdparameters/IdempotencyKeyschemas/CampaignOrderUpdateschemas/CampaignOrderresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CampaignOrderId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CampaignOrderUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrder"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveCampaignOrder
/v1/tenants/{tenant_id}/campaign-orders/{campaign_order_id}/archive

Archive a campaign order.

parameters/TenantIdparameters/CampaignOrderIdparameters/IdempotencyKeyschemas/CampaignOrderresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CampaignOrderId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrder"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST duplicateCampaignOrder
/v1/tenants/{tenant_id}/campaign-orders/{campaign_order_id}/duplicate

Copy a campaign order and, by default, its line items and weighted creative associations. Copies receive new references, DRAFT delivery statuses, and zero delivery counters. Existing creative records are reused. The source order is unchanged.

parameters/TenantIdparameters/CampaignOrderIdparameters/IdempotencyKeyschemas/CampaignOrderDuplicateRequestschemas/CampaignOrderresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CampaignOrderId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CampaignOrderDuplicateRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The new DRAFT campaign order (deep copy).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrder"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCampaignOrderStatusCounts
/v1/tenants/{tenant_id}/campaign-orders/status-counts

Per-status row counts for the tenant's campaign orders.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAdvertisers
/v1/tenants/{tenant_id}/advertisers

List a tenant's advertisers.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/AdvertiserListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of advertisers.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AdvertiserList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createAdvertiser
/v1/tenants/{tenant_id}/advertisers

Create an advertiser.

parameters/TenantIdparameters/IdempotencyKeyschemas/AdvertiserCreateschemas/Advertiserresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AdvertiserCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Advertiser"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAdvertiser
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}

Get an advertiser.

schemas/Advertiserresponses/Errorparameters/TenantIdparameters/AdvertiserId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    }
  ],
  "responses": {
    "200": {
      "description": "The advertiser.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Advertiser"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateAdvertiser
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}

Update an advertiser's name. ref is immutable after creation.

parameters/TenantIdparameters/AdvertiserIdparameters/IdempotencyKeyschemas/AdvertiserUpdateschemas/Advertiserresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AdvertiserUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Advertiser"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAdvertiserReportSummary
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}/report-summary

Read a delivery summary for one advertiser_id. A caller with the advertiser role can only read the advertiser bound to its identity.

schemas/AdvertiserReportSummaryresponses/Errorparameters/TenantIdparameters/AdvertiserId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    }
  ],
  "responses": {
    "200": {
      "description": "Advertiser-scoped report summary.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AdvertiserReportSummary"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAdvertiserCampaignOrders
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}/campaign-orders

List this advertiser's campaign orders. A caller with the advertiser role can only read orders for the advertiser bound to its identity.

parameters/TenantIdparameters/AdvertiserIdparameters/Limitparameters/Cursorschemas/CampaignOrderListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "Advertiser-scoped campaign orders.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CampaignOrderList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAdvertiserLineItems
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}/line-items

List line items under this advertiser's campaign orders. A caller with the advertiser role can only read the advertiser bound to its identity.

parameters/TenantIdparameters/AdvertiserIdparameters/Limitparameters/Cursorschemas/LineItemListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "Advertiser-scoped line items.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItemList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createAdvertiserLineItem
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}/line-items

Create a line item under one of this advertiser's campaign orders. Accepted fields are name, campaign_order_id, flight, goal, and rate. The advertiser role requires campaign.write and an identity bound to this advertiser.

parameters/TenantIdparameters/AdvertiserIdparameters/IdempotencyKeyschemas/AdvertiserLineItemWriteschemas/LineItemresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AdvertiserLineItemWrite"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created line item.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateAdvertiserLineItem
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}/line-items/{line_item_id}

Update name, flight, goal, or rate on a line item owned by this advertiser. Updates to another advertiser's line items are forbidden.

parameters/TenantIdparameters/AdvertiserIdparameters/LineItemIdparameters/IdempotencyKeyschemas/AdvertiserLineItemWriteschemas/LineItemresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AdvertiserLineItemWrite"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated line item.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveAdvertiser
/v1/tenants/{tenant_id}/advertisers/{advertiser_id}/archive

Archive an advertiser.

parameters/TenantIdparameters/AdvertiserIdparameters/IdempotencyKeyschemas/Advertiserresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Advertiser"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAdvertiserStatusCounts
/v1/tenants/{tenant_id}/advertisers/status-counts

Per-status row counts for the tenant's advertisers.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listLineItems
/v1/tenants/{tenant_id}/line-items

List a tenant's line items.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/LineItemListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "creative_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Only line items with this creative attached (line_item_creative)."
    }
  ],
  "responses": {
    "200": {
      "description": "A page of line items.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItemList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createLineItem
/v1/tenants/{tenant_id}/line-items

Create a line item (deliverable within an optional campaign order).

parameters/TenantIdparameters/IdempotencyKeyschemas/LineItemCreateschemas/LineItemresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/LineItemCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getLineItem
/v1/tenants/{tenant_id}/line-items/{line_item_id}

Get a line item.

schemas/LineItemresponses/Errorparameters/TenantIdparameters/LineItemId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    }
  ],
  "responses": {
    "200": {
      "description": "The line item.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateLineItem
/v1/tenants/{tenant_id}/line-items/{line_item_id}

Update a line item's name, cpm, priority, and delivery settings, including flight, pacing, audience, weighted creatives, and frequency caps. The kind is immutable.

parameters/TenantIdparameters/LineItemIdparameters/IdempotencyKeyschemas/LineItemUpdateschemas/LineItemresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/LineItemUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveLineItem
/v1/tenants/{tenant_id}/line-items/{line_item_id}/archive

Archive a line item.

parameters/TenantIdparameters/LineItemIdparameters/IdempotencyKeyschemas/LineItemresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST extendLineItem
/v1/tenants/{tenant_id}/line-items/{line_item_id}/extend

Archive the current line item and create a new one for the specified period. The new item has a fresh reference and keeps the source item's name, kind, cpm, priority, audience, and campaign order.

parameters/TenantIdparameters/LineItemIdparameters/IdempotencyKeyschemas/LineItemPeriodschemas/LineItemresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/LineItemPeriod"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The new line item covering the extended period.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST duplicateLineItem
/v1/tenants/{tenant_id}/line-items/{line_item_id}/duplicate

Create an INACTIVE copy of a line item with a new reference and the same configuration. The source line item is unchanged.

parameters/TenantIdparameters/LineItemIdparameters/IdempotencyKeyschemas/LineItemresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "201": {
      "description": "The inactive copy.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItem"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getLineItemEligibility
/v1/tenants/{tenant_id}/line-items/{line_item_id}/eligibility

Check whether a line item can serve using the serving engine's eligibility rules for order status, flight, dayparts, creatives, budgets, pacing, and caps. When the counter store is unavailable, counter-dependent checks return COUNTERS_UNAVAILABLE with severity INFO. The serving field is true only when no BLOCKING condition is present.

parameters/TenantIdparameters/LineItemIdschemas/EligibilityReportresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "name": "placement_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Optional placement to evaluate placement-scoped conditions against (GC-03). When set, the report additionally checks the placement's blocked_exclusion_labels against the line item's effective exclusion labels and emits PLACEMENT_EXCLUSION_LABEL_BLOCKED naming the blocking label.\n"
    }
  ],
  "responses": {
    "200": {
      "description": "The eligibility condition report.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EligibilityReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getLineItemDeliveryState
/v1/tenants/{tenant_id}/line-items/{line_item_id}/delivery-state

Read a line item's delivery state: PENDING, SERVING, GOAL_REACHED, FLIGHT_ENDED, or INACTIVE. The response uses live pacing counters and the serving engine's calculations for buffered goals, delivered and remaining counts, booked spend, hourly goals and weights, bid-rate caps, and dynamic eCPM for budget-and-goal line items.

schemas/LineItemDeliveryStateresponses/Errorparameters/TenantIdparameters/LineItemId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    }
  ],
  "responses": {
    "200": {
      "description": "The computed delivery state.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItemDeliveryState"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST resetLineItemDelivery
/v1/tenants/{tenant_id}/line-items/{line_item_id}/reset-delivery

Reset a line item's lifetime and current-day impression, spend, click, conversion, and hourly counters, then return its recomputed PENDING delivery state. Frequency-cap records are retained. The change is audited. Returns UNAVAILABLE when the console has no hot-store connection, configured by RIPTIDE_REDIS_ADDR.

parameters/TenantIdparameters/LineItemIdparameters/IdempotencyKeyschemas/LineItemDeliveryStateresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/LineItemId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "The delivery state after the reset.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItemDeliveryState"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST bulkUpdateLineItemStatus
/v1/tenants/{tenant_id}/line-items/bulk-status

Activate, pause, or archive up to 100 line items. Returns a separate success or machine-readable error for each ID, including activation errors for items without a servable creative. A failed item does not roll back successful changes to other items.

parameters/TenantIdparameters/IdempotencyKeyschemas/LineItemBulkStatusRequestschemas/LineItemBulkStatusResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/LineItemBulkStatusRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-item results, in request order.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/LineItemBulkStatusResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getLineItemStatusCounts
/v1/tenants/{tenant_id}/line-items/status-counts

Per-status row counts for the tenant's line items.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCreatives
/v1/tenants/{tenant_id}/creatives

List a tenant's creatives.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/CreativeListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of creatives.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createCreative
/v1/tenants/{tenant_id}/creatives

Create a creative (VAST tag / hosted media / display).

parameters/TenantIdparameters/IdempotencyKeyschemas/CreativeCreateschemas/Creativeresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreativeCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Creative"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST bulkImportCreatives
/v1/tenants/{tenant_id}/creatives/bulk-import

Create or update creatives by ref from a JSON array. Return a result for each row. With dry_run: true, validate without saving changes. Existing references are updated; new references create creatives.

parameters/TenantIdparameters/IdempotencyKeyschemas/CreativeBulkImportRequestschemas/CreativeBulkImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreativeBulkImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row results (dry-run preview or applied upsert).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeBulkImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCreative
/v1/tenants/{tenant_id}/creatives/{creative_id}

Get a creative.

schemas/Creativeresponses/Errorparameters/TenantIdparameters/CreativeId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    }
  ],
  "responses": {
    "200": {
      "description": "The creative.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Creative"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateCreative
/v1/tenants/{tenant_id}/creatives/{creative_id}

Update a creative's VAST URL or XML, duration, click URL, verification, and proximity fields. The kind is immutable. Use the pipeline action to advance processing status.

parameters/TenantIdparameters/CreativeIdparameters/IdempotencyKeyschemas/CreativeUpdateschemas/Creativeresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreativeUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Creative"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveCreative
/v1/tenants/{tenant_id}/creatives/{creative_id}/archive

Archive a creative.

parameters/TenantIdparameters/CreativeIdparameters/IdempotencyKeyschemas/Creativeresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Creative"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST advanceCreativePipeline
/v1/tenants/{tenant_id}/creatives/{creative_id}/pipeline/advance

Advance a creative through UPLOADED, STORED, WATERMARKED, TRANSCODED, and READY one step at a time. Reaching READY approves a PENDING creative only when the tenant's creative_auto_approve policy is enabled. Otherwise, approval stays PENDING until reviewCreative is called.

parameters/TenantIdparameters/CreativeIdparameters/IdempotencyKeyschemas/Creativeresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "The creative after advancing one pipeline step.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Creative"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST reviewCreative
/v1/tenants/{tenant_id}/creatives/{creative_id}/review

Approve or reject a creative with a reason_code and feedback. The creative records the decision, actor, and time in approval_reason, approval_feedback, reviewed_at, and reviewed_by. Rejection requires reason_code. When creative_auto_approve is disabled, a material change to markup, click settings, or media resets APPROVED to PENDING for another review.

parameters/TenantIdparameters/CreativeIdparameters/IdempotencyKeyschemas/CreativeReviewRequestschemas/Creativeresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreativeReviewRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The creative after the review decision.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Creative"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createCreativeMediaUpload
/v1/tenants/{tenant_id}/creatives/{creative_id}/media

Upload media for a hosted creative as multipart/form-data under file. An optional content_type overrides the file part's Content-Type. Returns 202; poll getCreativeMediaUpload for RECEIVED, VALIDATED, TRANSCODING, READY, or FAILED with an error. READY adds the media_variant_id and preview_url to the upload record and the creative's media variants. Requires campaign.write.

parameters/TenantIdparameters/CreativeIdparameters/IdempotencyKeyschemas/CreativeMediaUploadFormschemas/CreativeMediaUploadresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "multipart/form-data": {
        "schema": {
          "$ref": "#/components/schemas/CreativeMediaUploadForm"
        }
      }
    }
  },
  "responses": {
    "202": {
      "description": "The accepted upload record (status RECEIVED).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeMediaUpload"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCreativeMediaUpload
/v1/tenants/{tenant_id}/creatives/{creative_id}/media/{upload_id}

Read a media upload's status, validated content type, size, and SHA-256 hash. Once READY, the record also includes media_variant_id and preview_url. Requires campaign.read.

schemas/CreativeMediaUploadresponses/Errorparameters/TenantIdparameters/CreativeIdparameters/CreativeMediaUploadId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/CreativeId"
    },
    {
      "$ref": "#/components/parameters/CreativeMediaUploadId"
    }
  ],
  "responses": {
    "200": {
      "description": "The upload record.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreativeMediaUpload"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCreativeStatusCounts
/v1/tenants/{tenant_id}/creatives/status-counts

Per-status row counts for the tenant's creatives.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listFeeSchedules
/v1/tenants/{tenant_id}/fee-schedules

List a tenant's fee schedules.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/FeeScheduleListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of fee schedules.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FeeScheduleList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createFeeSchedule
/v1/tenants/{tenant_id}/fee-schedules

Create a fee schedule for a scope, with platform, demand, publisher, or serving fee lines using REVSHARE, CPM, or FLAT pricing. Only one schedule is allowed per tenant, scope, and scope_id; a duplicate returns CONFLICT. The change is audited and access is restricted to the tenant.

parameters/TenantIdparameters/IdempotencyKeyschemas/FeeScheduleCreateschemas/FeeScheduleresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/FeeScheduleCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FeeSchedule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getFeeSchedule
/v1/tenants/{tenant_id}/fee-schedules/{fee_schedule_id}

Get a fee schedule.

schemas/FeeScheduleresponses/Errorparameters/TenantIdparameters/FeeScheduleId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/FeeScheduleId"
    }
  ],
  "responses": {
    "200": {
      "description": "The fee schedule.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FeeSchedule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateFeeSchedule
/v1/tenants/{tenant_id}/fee-schedules/{fee_schedule_id}

Replace a fee schedule's name and fee lines. The scope and scope_id are immutable; create a new schedule to change them. The change is audited and access is restricted to the tenant.

parameters/TenantIdparameters/FeeScheduleIdparameters/IdempotencyKeyschemas/FeeScheduleUpdateschemas/FeeScheduleresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/FeeScheduleId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/FeeScheduleUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FeeSchedule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveFeeSchedule
/v1/tenants/{tenant_id}/fee-schedules/{fee_schedule_id}/archive

Archive a fee schedule.

parameters/TenantIdparameters/FeeScheduleIdparameters/IdempotencyKeyschemas/FeeScheduleresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/FeeScheduleId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FeeSchedule"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getFeeScheduleStatusCounts
/v1/tenants/{tenant_id}/fee-schedules/status-counts

Per-status row counts for the tenant's fee schedules.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listModels
/v1/tenants/{tenant_id}/models

List models for a decision_point, including the tenant's models and platform-shared models. The decision_point is required and can be bid, floor, traffic_shape, pace, creative, audience, insight, or anomaly.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ModelRegistryEntryListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "decision_point",
      "in": "query",
      "required": true,
      "schema": {
        "type": "string"
      }
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of models.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ModelRegistryEntryList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createModel
/v1/tenants/{tenant_id}/models

Register a model owned by the tenant for a decision point. Only operators can add platform-shared models.

parameters/TenantIdparameters/IdempotencyKeyschemas/ModelCreateRequestschemas/ModelRegistryEntryresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ModelCreateRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Registered model.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ModelRegistryEntry"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getModel
/v1/tenants/{tenant_id}/models/{model_id}

Read a tenant-owned or platform-shared model by ID.

schemas/ModelRegistryEntryresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "model_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "The model.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ModelRegistryEntry"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST assignModel
/v1/tenants/{tenant_id}/models/{model_id}/assignments

Assign a model available to the tenant to a decision point in SHADOW, BOUNDED_AB, or LIVE mode. Repeating the same tenant, decision point, mode, and model assignment is idempotent.

parameters/TenantIdparameters/IdempotencyKeyschemas/ModelAssignmentRequestschemas/ModelAssignmentresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "model_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ModelAssignmentRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Assignment recorded.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ModelAssignment"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST recordEvaluationRun
/v1/tenants/{tenant_id}/models/{model_id}/evaluation-runs

Record candidate and baseline metrics for a model available to the tenant, for one decision point and objective. This operation saves the evaluation only. Use promoteModel to change the model's operating mode.

parameters/TenantIdparameters/IdempotencyKeyschemas/ModelEvaluationRunRequestschemas/ModelEvaluationRunresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "model_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ModelEvaluationRunRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Evaluation run recorded.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ModelEvaluationRun"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST promoteModel
/v1/tenants/{tenant_id}/models/{model_id}/promote

Change a model's mode to SHADOW, BOUNDED_AB, or LIVE for a decision point, including rollback to an earlier mode. Requires platform operator access. The operation records a promotion event and an audit record.

parameters/TenantIdparameters/IdempotencyKeyschemas/ModelPromoteRequestschemas/ModelPromotionEventresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "model_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ModelPromoteRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Promoted.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ModelPromotionEvent"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listReconciliationStatements
/v1/tenants/{tenant_id}/reconciliation/statements

List imported partner statements, newest first.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ReconciliationStatementListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "partner_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of statements.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationStatementList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST importReconciliationStatement
/v1/tenants/{tenant_id}/reconciliation/statements

Import a partner statement (rows already parsed from the partner's CSV / API export) for one partner and period. Rows are stored verbatim; comparison runs separately.

parameters/TenantIdparameters/IdempotencyKeyschemas/ReconciliationStatementImportschemas/ReconciliationStatementresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReconciliationStatementImport"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The stored statement.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationStatement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getReconciliationStatement
/v1/tenants/{tenant_id}/reconciliation/statements/{statement_id}

Get one imported statement with its rows.

schemas/ReconciliationStatementresponses/Errorparameters/TenantIdparameters/ReconciliationStatementId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ReconciliationStatementId"
    }
  ],
  "responses": {
    "200": {
      "description": "The statement.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationStatement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runReconciliationCompare
/v1/tenants/{tenant_id}/reconciliation/compare

Run a compare job: the statement's per-day impressions and amounts against the platform's own receipts / usage for the same partner and period, with tolerance thresholds. Produces a discrepancy report (persisted; listReconciliationReports).

parameters/TenantIdparameters/IdempotencyKeyschemas/ReconciliationCompareRequestschemas/ReconciliationReportresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReconciliationCompareRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The discrepancy report.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listReconciliationReports
/v1/tenants/{tenant_id}/reconciliation/reports

List discrepancy reports, newest first.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ReconciliationReportListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "statement_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of reports.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationReportList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getReconciliationReport
/v1/tenants/{tenant_id}/reconciliation/reports/{report_id}

Get one discrepancy report with its per-day lines.

schemas/ReconciliationReportresponses/Errorparameters/TenantIdparameters/ReconciliationReportId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ReconciliationReportId"
    }
  ],
  "responses": {
    "200": {
      "description": "The report.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST setReconciliationAdjustmentMemo
/v1/tenants/{tenant_id}/reconciliation/reports/{report_id}/adjustment-memo

Record how a DISCREPANT reconciliation report was resolved with a partner, such as a credit, accepted tolerance, or agreed rerun. Replaces the previous memo and records adjustment_memo_by and adjustment_memo_at. Requires billing.write.

parameters/TenantIdparameters/ReconciliationReportIdparameters/IdempotencyKeyschemas/ReconciliationAdjustmentMemoRequestschemas/ReconciliationReportresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ReconciliationReportId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReconciliationAdjustmentMemoRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The report with the memo recorded.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getTenantRatePlan
/v1/tenants/{tenant_id}/rate-plan

Get the platform rate plan assigned to this tenant (tenant.plan_id → rate_plan). 404 when no plan is assigned.

schemas/PlatformRatePlanresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "The tenant's rate plan.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformRatePlan"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listUsageRecords
/v1/tenants/{tenant_id}/usage

List aggregated tenant usage for a period.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/UsageRecordListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "period_start",
      "in": "query",
      "required": true,
      "schema": {
        "type": "string",
        "format": "date-time"
      }
    },
    {
      "name": "period_end",
      "in": "query",
      "required": true,
      "schema": {
        "type": "string",
        "format": "date-time"
      }
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "Usage records in the period.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UsageRecordList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCostTelemetry
/v1/tenants/{tenant_id}/cost-telemetry

List tenant cost estimates derived from recorded usage for a period. These are operational estimates; invoice and payment state are available through the billing endpoints.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/CostTelemetryListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "period_start",
      "in": "query",
      "required": true,
      "schema": {
        "type": "string",
        "format": "date-time"
      }
    },
    {
      "name": "period_end",
      "in": "query",
      "required": true,
      "schema": {
        "type": "string",
        "format": "date-time"
      }
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "Cost telemetry rows in the period.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CostTelemetryList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCostTelemetry
/v1/tenants/{tenant_id}/cost-telemetry/{cost_telemetry_id}

Get one derived cost telemetry row by its usage_record source_hash.

schemas/CostTelemetryresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "cost_telemetry_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string"
      },
      "description": "The usage_record source_hash backing this derived cost telemetry row."
    }
  ],
  "responses": {
    "200": {
      "description": "The derived cost telemetry row.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CostTelemetry"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPrepaidBalance
/v1/tenants/{tenant_id}/billing/prepaid/balance

Read the tenant's prepaid ledger balance for a currency.

parameters/TenantIdschemas/PrepaidBalanceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "currency",
      "in": "query",
      "required": true,
      "schema": {
        "type": "string",
        "minLength": 3,
        "maxLength": 3
      },
      "description": "ISO 4217 currency code (e.g. USD)."
    }
  ],
  "responses": {
    "200": {
      "description": "Current prepaid balance.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PrepaidBalance"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST topUpPrepaid
/v1/tenants/{tenant_id}/billing/prepaid/top-up

Credit the tenant's prepaid ledger. Requires billing.write. The riptide.billing.top_up_prepaid MCP tool requires human approval for amounts above 10000 settlement units; this is an MCP control rather than an HTTP approval workflow.

parameters/TenantIdparameters/IdempotencyKeyschemas/PrepaidTopUpCreateschemas/PrepaidTopUpResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PrepaidTopUpCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Ledger entry applied (or idempotent replay).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PrepaidTopUpResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getTenantQuotaState
/v1/tenants/{tenant_id}/billing/quota-state

Read whether the tenant can serve: ok, quota_exceeded when daily requests reach request_quota_per_day, or suspended when the prepaid balance is exhausted. The serving plan uses this verdict. A tenant without a recorded verdict returns ok.

schemas/TenantQuotaStateresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Current quota / prepaid state.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantQuotaState"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listFxRates
/v1/operator/fx/rates

List cached USD multipliers by currency, with the source snapshot date and cache age. Operator access required. Results use cursor pagination by currency code. The age_seconds and stale fields describe the entire cache.

parameters/Limitparameters/Cursorschemas/FxRateListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "Cached FX rates.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FxRateList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST refreshFxRates
/v1/operator/fx/refresh

Refresh the currency-rate cache from the configured source immediately. Operator access required. Scheduled meter refreshes continue separately. Returns 412 when RIPTIDE_FX_SOURCE_URL is unset.

parameters/IdempotencyKeyschemas/FxRefreshResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "The refreshed snapshot.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FxRefreshResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAdvertiserInvoices
/v1/tenants/{tenant_id}/advertiser-invoices

List the tenant's advertiser invoices, newest period first, with cursor pagination. Use advertiser_id to filter by customer. Billing access is sufficient; the ad_server module entitlement is not required.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/InvoiceStatusschemas/InvoiceListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "advertiser_id",
      "in": "query",
      "required": false,
      "description": "Only invoices issued to this advertiser.",
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Only invoices in this lifecycle status.",
      "schema": {
        "$ref": "#/components/schemas/InvoiceStatus"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of advertiser invoices.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InvoiceList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAdvertiserInvoice
/v1/tenants/{tenant_id}/advertiser-invoices/{invoice_id}

Get one advertiser invoice with its totals and proof of performance.

schemas/Invoiceresponses/Errorparameters/TenantIdparameters/InvoiceId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InvoiceId"
    }
  ],
  "responses": {
    "200": {
      "description": "The advertiser invoice.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Invoice"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listInvoices
/v1/tenants/{tenant_id}/invoices

List platform invoices for a tenant (newest first).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/PlatformInvoiceListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of invoices.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformInvoiceList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getInvoice
/v1/tenants/{tenant_id}/invoices/{invoice_id}

Get one platform invoice by id (tenant-scoped).

schemas/PlatformInvoiceresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "invoice_id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "The invoice.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformInvoice"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST transitionInvoice
/v1/tenants/{tenant_id}/invoices/{invoice_id}/transition

Advance a platform invoice from DRAFT to REVIEW, ISSUED, and PAID, or mark it VOID before payment. Issuing assigns an invoice number, freezes the FX snapshot and tax lines, and starts payment collection. Payment-provider webhooks normally mark invoices PAID; manual payment marking is for off-platform payments. An invalid transition returns 409 CONFLICT with hint invoice_transition_illegal. The reason is audited.

parameters/TenantIdparameters/InvoiceIdparameters/IdempotencyKeyschemas/InvoiceTransitionRequestschemas/PlatformInvoiceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InvoiceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/InvoiceTransitionRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The invoice in its new status.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformInvoice"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getInvoiceDocument
/v1/tenants/{tenant_id}/invoices/{invoice_id}/document

Render an invoice statement as HTML or PDF, using the same rendering as the emailed statement. Documents are available for ISSUED, PAID, and VOID invoices; VOID documents carry a watermark. DRAFT and REVIEW invoices return 409 CONFLICT.

parameters/TenantIdparameters/InvoiceIdschemas/InvoiceDocumentFormatresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InvoiceId"
    },
    {
      "name": "format",
      "in": "query",
      "required": false,
      "description": "Document format; html when omitted.",
      "schema": {
        "$ref": "#/components/schemas/InvoiceDocumentFormat"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "The rendered statement.",
      "content": {
        "text/html": {
          "schema": {
            "type": "string"
          }
        },
        "application/pdf": {
          "schema": {
            "type": "string",
            "format": "binary"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createInvoiceCredit
/v1/tenants/{tenant_id}/invoices/{invoice_id}/credits

Apply a credit that reduces an invoice's amount due to a minimum of zero. An ISSUED invoice becomes PAID when the remaining amount reaches zero. PAID or VOID invoices reject credits with 409 CONFLICT. The reason is audited.

parameters/TenantIdparameters/InvoiceIdparameters/IdempotencyKeyschemas/InvoiceCreditCreateschemas/InvoiceCreditresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InvoiceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/InvoiceCreditCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The recorded credit.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InvoiceCredit"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createInvoiceAdjustment
/v1/tenants/{tenant_id}/invoices/{invoice_id}/adjustments

Add a positive or negative adjustment to a DRAFT or REVIEW invoice. After issuance, adjustments return 409 CONFLICT; use a credit instead. The reason is audited.

parameters/TenantIdparameters/InvoiceIdparameters/IdempotencyKeyschemas/InvoiceAdjustmentCreateschemas/InvoiceAdjustmentresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InvoiceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/InvoiceAdjustmentCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The recorded adjustment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InvoiceAdjustment"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDunningState
/v1/tenants/{tenant_id}/invoices/{invoice_id}/dunning

Read an issued invoice's payment collection status, including charge attempts, the next retry time, and whether serving was suspended for non-payment. Returns 404 for invoices that have not entered payment collection.

schemas/DunningStateresponses/Errorparameters/TenantIdparameters/InvoiceId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InvoiceId"
    }
  ],
  "responses": {
    "200": {
      "description": "The dunning state.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DunningState"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listWalletBindings
/v1/tenants/{tenant_id}/wallet-bindings

List advertiser-to-prepaid-wallet bindings with cursor pagination.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/WalletBindingListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "advertiser_id",
      "in": "query",
      "required": false,
      "description": "Only the binding of this advertiser.",
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of wallet bindings.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WalletBindingList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT setWalletBinding
/v1/tenants/{tenant_id}/wallet-bindings/{advertiser_id}

Create or replace an advertiser's prepaid wallet binding. Delivery reduces the wallet balance. With auto_pause enabled, the advertiser's line items pause when the balance reaches zero and resume after a top-up.

parameters/TenantIdparameters/AdvertiserIdparameters/IdempotencyKeyschemas/WalletBindingSetschemas/WalletBindingresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AdvertiserId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/WalletBindingSet"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The binding as stored.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WalletBinding"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runVendorSettlement
/v1/tenants/{tenant_id}/vendor-settlements/run

Start settlement for a period by combining publisher payout statements and partner costs, then submitting payable rows to the tenant's payout provider. Returns 202 while processing continues. A second run for the same period returns 409 CONFLICT while the previous run is active.

parameters/TenantIdparameters/IdempotencyKeyschemas/VendorSettlementRunRequestschemas/VendorSettlementRunresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/VendorSettlementRunRequest"
        }
      }
    }
  },
  "responses": {
    "202": {
      "description": "The settlement run that was started.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/VendorSettlementRun"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listMarketplaceSettlements
/v1/tenants/{tenant_id}/marketplace-settlements

List amounts the tenant owes or is owed for each period, listing, and counterparty, based on path receipts net of fees. Results are newest period first and use cursor pagination.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/MarketplaceSettlementStatusschemas/MarketplaceSettlementListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "period",
      "in": "query",
      "required": false,
      "description": "Only settlements of this calendar month (YYYY-MM).",
      "schema": {
        "type": "string",
        "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$"
      }
    },
    {
      "name": "listing_id",
      "in": "query",
      "required": false,
      "description": "Only settlements of this listing.",
      "schema": {
        "type": "string",
        "format": "uuid"
      }
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Only settlements in this status.",
      "schema": {
        "$ref": "#/components/schemas/MarketplaceSettlementStatus"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of marketplace settlements.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceSettlementList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runMarketplaceSettlement
/v1/tenants/{tenant_id}/marketplace-settlements/run

Settle marketplace activity for a period using receipts added since the previous run. Writes a settlement row per listing and counterparty and advances the receipt cursor. Returns 202 while processing continues. Repeating a period processes only receipts not included in earlier runs.

parameters/TenantIdparameters/IdempotencyKeyschemas/MarketplaceSettlementRunRequestschemas/MarketplaceSettlementRunresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/MarketplaceSettlementRunRequest"
        }
      }
    }
  },
  "responses": {
    "202": {
      "description": "The settlement run summary.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/MarketplaceSettlementRun"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listRatePlans
/v1/operator/rate-plans

List platform rate plans. Operator access required.

parameters/Limitparameters/Cursorschemas/PlatformRatePlanListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of rate plans.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformRatePlanList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createRatePlan
/v1/operator/rate-plans

Add a platform rate plan. Operator access required. The name is unique; repeating a request with the same name returns the existing plan.

parameters/IdempotencyKeyschemas/RatePlanCreateschemas/PlatformRatePlanresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/RatePlanCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created (or the existing plan of that name).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformRatePlan"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listUsers
/v1/tenants/{tenant_id}/users

List a tenant's console users.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/UserListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of users.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UserList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createUser
/v1/tenants/{tenant_id}/users

Create a console user (email/name). Prefer invites for role assignment + magic link.

parameters/TenantIdparameters/IdempotencyKeyschemas/UserCreateschemas/Userresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/UserCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/User"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listInvites
/v1/tenants/{tenant_id}/invites

List pending, expired, and revoked tenant invitations. Requires tenant_admin.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/InviteStatusschemas/InviteListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
        "$ref": "#/components/schemas/InviteStatus"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of invites, newest first.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InviteList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createInvite
/v1/tenants/{tenant_id}/invites

Invite a user by email with a role; sends a magic link (tenant_admin).

parameters/TenantIdparameters/IdempotencyKeyschemas/InviteCreateschemas/AuthAcceptedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/InviteCreate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Invite accepted (enumerate-safe ok body).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AuthAccepted"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST resendInvite
/v1/tenants/{tenant_id}/invites/{invite_id}/resend

Re-issue a pending invite's magic link (a fresh challenge; the previous link stops working).

parameters/TenantIdparameters/InviteIdparameters/IdempotencyKeyschemas/Inviteresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InviteId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "The re-issued invite.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Invite"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST revokeInvite
/v1/tenants/{tenant_id}/invites/{invite_id}/revoke

Revoke a pending invite; its magic link can no longer be redeemed.

parameters/TenantIdparameters/InviteIdparameters/IdempotencyKeyschemas/Inviteresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InviteId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "The revoked invite.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Invite"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getUser
/v1/tenants/{tenant_id}/users/{user_id}

Get a console user.

schemas/Userresponses/Errorparameters/TenantIdparameters/UserId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/UserId"
    }
  ],
  "responses": {
    "200": {
      "description": "The user.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/User"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateUser
/v1/tenants/{tenant_id}/users/{user_id}

Update a console user's name and/or role set. email is immutable after creation.

parameters/TenantIdparameters/UserIdparameters/IdempotencyKeyschemas/UserUpdateschemas/Userresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/UserId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/UserUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/User"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST suspendUser
/v1/tenants/{tenant_id}/users/{user_id}/suspend

Suspend a console user.

parameters/TenantIdparameters/UserIdparameters/IdempotencyKeyschemas/Userresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/UserId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Suspended.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/User"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST reactivateUser
/v1/tenants/{tenant_id}/users/{user_id}/reactivate

Reactivate a suspended console user.

parameters/TenantIdparameters/UserIdparameters/IdempotencyKeyschemas/Userresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/UserId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Reactivated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/User"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getUserStatusCounts
/v1/tenants/{tenant_id}/users/status-counts

Per-status row counts for the tenant's console users.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listAudiences
/v1/tenants/{tenant_id}/audiences

List a tenant's audiences (reusable targeting definitions).

parameters/TenantIdparameters/Limitparameters/Cursorschemas/AudienceListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of audiences.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AudienceList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createAudience
/v1/tenants/{tenant_id}/audiences

Create an audience with keys, duration, custom_rules, and inclusion and exclusion rule arrays.

parameters/TenantIdparameters/IdempotencyKeyschemas/AudienceCreateschemas/Audienceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AudienceCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Audience"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAudience
/v1/tenants/{tenant_id}/audiences/{audience_id}

Get an audience.

schemas/Audienceresponses/Errorparameters/TenantIdparameters/AudienceId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AudienceId"
    }
  ],
  "responses": {
    "200": {
      "description": "The audience.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Audience"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateAudience
/v1/tenants/{tenant_id}/audiences/{audience_id}

Update an audience. Supplied rule arrays replace the complete stored array; omitted arrays remain unchanged.

parameters/TenantIdparameters/AudienceIdparameters/IdempotencyKeyschemas/AudienceUpdateschemas/Audienceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AudienceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AudienceUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Audience"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveAudience
/v1/tenants/{tenant_id}/audiences/{audience_id}/archive

Archive an audience.

parameters/TenantIdparameters/AudienceIdparameters/IdempotencyKeyschemas/Audienceresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/AudienceId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Audience"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAudienceStatusCounts
/v1/tenants/{tenant_id}/audiences/status-counts

Per-status row counts for the tenant's audiences.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Status counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getReportsCatalog
/v1/tenants/{tenant_id}/reports/catalog

Read available reporting metrics and dimensions, including units, descriptions, supported storage tiers, and query limits. Use this catalog to populate metric and dimension choices in clients.

schemas/ReportCatalogresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Catalog.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportCatalog"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runReport
/v1/tenants/{tenant_id}/reports/run

Run a report using the reporting catalog. The platform compiles the query and selects an eligible hot, warm, or cold table. With ClickHouse configured, it executes the query and returns rows. Otherwise, it returns the compiled query with no result rows.

schemas/ReportRunRequestschemas/ReportRunResponseresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReportRunRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Report result.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportRunResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST reportingChat
/v1/tenants/{tenant_id}/reports/chat

Ask the reporting assistant a read-only question. It uses permitted reporting and insight tools and returns supporting evidence. Numeric answers come from run_report, ask_question, compare_periods, or explain_change results. The assistant does not change configuration or accept free-form SQL.

schemas/ReportingChatRequestschemas/ReportingChatReplyresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReportingChatRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Assistant reply with evidence and optional ReportSpec to apply in Explore.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportingChatReply"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getReportsLive
/v1/tenants/{tenant_id}/reports/live

Read counters held by the current console process. These counters are not connected to the production event stream and remain empty unless updated within the process. For production traffic, use reports/run with ClickHouse configured through RIPTIDE_CLICKHOUSE_DSN.

parameters/TenantIdschemas/ReportLiveResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "name": "placement_id",
      "in": "query",
      "required": false,
      "description": "Restrict the snapshot to one placement id.",
      "schema": {
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Live counter snapshot.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportLiveResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET streamReportsLive
/v1/tenants/{tenant_id}/reports/stream

Read the current process-local counters as a server-sent event. This operation sends one snapshot event and closes the connection. It uses the same counters and has the same production-data limitation as getReportsLive.

responses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "One SSE `snapshot` event carrying the live counter snapshot.",
      "content": {
        "text/event-stream": {
          "schema": {
            "type": "string"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getAttributionConfig
/v1/tenants/{tenant_id}/attribution-config

Get the tenant's conversion attribution config (deterministic last-touch: click-through + view-through windows). When no row has been written yet, returns the platform defaults (7d click window, 1d view window, view-through enabled) with a nil id.

schemas/AttributionConfigresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "The attribution config.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AttributionConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateAttributionConfig
/v1/tenants/{tenant_id}/attribution-config

Upsert the tenant's conversion attribution config (one row per tenant in v1). Omitted fields keep their current (or default) values.

parameters/TenantIdparameters/IdempotencyKeyschemas/AttributionConfigUpdateschemas/AttributionConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/AttributionConfigUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AttributionConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST forecastAvailability
/v1/tenants/{tenant_id}/forecasts/availability

Forecast inventory from recent request volume by placement and day of week, subtracting overlapping bookings with an equal or higher PriorityClass. This operation makes no changes. Empty history returns zero capacity with LOW confidence.

schemas/ForecastAvailabilityRequestschemas/AvailabilityForecastResultresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ForecastAvailabilityRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Availability forecast metrics for the requested slice and range.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AvailabilityForecastResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST forecastDelivery
/v1/tenants/{tenant_id}/forecasts/delivery

Forecast delivery for a proposed flight using capacity available at its PriorityClass and even pacing. Deliverable volume is the smaller of availability and the goal; the response reports any shortfall. This operation makes no changes.

schemas/ForecastDeliveryRequestschemas/DeliveryForecastResultresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ForecastDeliveryRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Delivery forecast metrics for the proposed flight.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeliveryForecastResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getUserProfile
/v1/tenants/{tenant_id}/profiles/{user_key}

Read a user profile from the cell profile store using an opaque user_key. Keep email addresses and phone numbers out of the identifier. Returns 404 when the profile is absent.

schemas/UserProfileschemas/Errorresponses/Errorparameters/TenantIdparameters/UserKey

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/UserKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Profile snapshot.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UserProfile"
          }
        }
      }
    },
    "404": {
      "description": "Profile not found (miss or prior RTBF erase).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT upsertUserProfile
/v1/tenants/{tenant_id}/profiles/{user_key}

Create or update profile attributes, tags, segments, and opt-out status for a tenant and user_key. This control-plane operation is separate from ad serving. Supports up to 64 attributes, 32 tags, and 128 segments.

parameters/TenantIdparameters/UserKeyparameters/IdempotencyKeyschemas/UserProfileUpsertschemas/UserProfileresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/UserKey"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/UserProfileUpsert"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Upserted profile snapshot.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UserProfile"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
DELETE deleteUserProfile
/v1/tenants/{tenant_id}/profiles/{user_key}

Right-to-be-forgotten erase for (tenant, user_key): clears attributes, tags, and segment membership. Subsequent GET misses. Idempotent on already-absent keys.

parameters/TenantIdparameters/UserKeyparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/UserKey"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Erased (or already absent)."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST ingestConversions
/v1/tenants/{tenant_id}/conversions:ingest

Ingest server-side conversion events from an advertiser's backend. Each accepted event is validated and published as a CONVERSION event subject to the tenant's privacy controls. Rejected rows are reported by index; accepted rows continue processing. Returns 202. Identical batches are deduplicated by their SHA-256 digest.

parameters/TenantIdparameters/IdempotencyKeyschemas/ConversionIngestBatchschemas/ConversionIngestResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ConversionIngestBatch"
        }
      }
    }
  },
  "responses": {
    "202": {
      "description": "The batch receipt (accepted / rejected counts and the batch digest).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ConversionIngestResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getConversionTag
/v1/tenants/{tenant_id}/conversion-tag

Return conversion pixel HTML and server-to-server endpoint templates for the tenant. The snippets use the sealed click_ref join key, rt_clkref or clkref, and exclude personally identifying data.

schemas/ConversionTagresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Conversion tag / pixel snippets.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ConversionTag"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listWebhookSubscriptions
/v1/tenants/{tenant_id}/webhooks

List the tenant's webhook subscriptions. Signing secrets are excluded from the response.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/WebhookSubscriptionListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of webhook subscriptions.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WebhookSubscriptionList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createWebhookSubscription
/v1/tenants/{tenant_id}/webhooks

Create a webhook subscription with HMAC-signed delivery and retries.

parameters/TenantIdparameters/IdempotencyKeyschemas/WebhookSubscriptionCreateschemas/WebhookSubscriptionCreatedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/WebhookSubscriptionCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created. The response includes secret exactly once; it is never returned again.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WebhookSubscriptionCreated"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST previewFeeSchedule
/v1/tenants/{tenant_id}/fee-schedules/preview

Preview which saved fee schedule applies to specified scope IDs and a fee kind, using the same precedence rules as the serving plan. This operation makes no changes.

schemas/FeeSchedulePreviewRequestschemas/FeeSchedulePreviewResponseresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/FeeSchedulePreviewRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The resolved entry, if any.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/FeeSchedulePreviewResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getWebhookSubscription
/v1/tenants/{tenant_id}/webhooks/{webhook_subscription_id}

Read a webhook subscription. Its signing secret is excluded from the response.

schemas/WebhookSubscriptionresponses/Errorparameters/TenantIdparameters/WebhookSubscriptionId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/WebhookSubscriptionId"
    }
  ],
  "responses": {
    "200": {
      "description": "The subscription.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WebhookSubscription"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateWebhookSubscription
/v1/tenants/{tenant_id}/webhooks/{webhook_subscription_id}

Update a webhook subscription's URL, subscribed events, or active flag.

parameters/TenantIdparameters/WebhookSubscriptionIdparameters/IdempotencyKeyschemas/WebhookSubscriptionUpdateschemas/WebhookSubscriptionresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/WebhookSubscriptionId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/WebhookSubscriptionUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WebhookSubscription"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
DELETE deleteWebhookSubscription
/v1/tenants/{tenant_id}/webhooks/{webhook_subscription_id}

Delete a webhook subscription.

parameters/TenantIdparameters/WebhookSubscriptionIdparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/WebhookSubscriptionId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Deleted."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listWebhookDeliveries
/v1/tenants/{tenant_id}/webhooks/{webhook_subscription_id}/deliveries

List webhook deliveries, newest first, with cursor pagination. Each record includes its attempt count, last status code or error, and next retry time. Deliveries that exhaust their retries have status DEAD.

parameters/TenantIdparameters/WebhookSubscriptionIdparameters/Limitparameters/Cursorschemas/WebhookDeliveryListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/WebhookSubscriptionId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of deliveries.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WebhookDeliveryList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST replayWebhookDelivery
/v1/tenants/{tenant_id}/webhooks/{webhook_subscription_id}/deliveries/{webhook_delivery_id}/replay

Re-enqueue a delivery (DELIVERED or DEAD) as a fresh PENDING delivery with a new delivery id and replay_of pointing at the original. The original row is left untouched; the new one goes through the normal retry policy.

parameters/TenantIdparameters/WebhookSubscriptionIdparameters/WebhookDeliveryIdparameters/IdempotencyKeyschemas/WebhookDeliveryresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/WebhookSubscriptionId"
    },
    {
      "$ref": "#/components/parameters/WebhookDeliveryId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "201": {
      "description": "The new delivery.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WebhookDelivery"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST rotateWebhookSecret
/v1/tenants/{tenant_id}/webhooks/{webhook_subscription_id}/rotate-secret

Rotate the subscription's signing secret. The response carries the new secret exactly once. For grace_seconds (default 86400, max 604800) deliveries are signed under both the new and the previous secret (multiple v1 entries in X-Riptide-Webhook-Signature-256), so a receiver can switch keys without a verification gap.

parameters/TenantIdparameters/WebhookSubscriptionIdparameters/IdempotencyKeyschemas/WebhookSecretRotateRequestschemas/WebhookSecretRotatedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/WebhookSubscriptionId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": false,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/WebhookSecretRotateRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Rotated; the new secret is returned once.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/WebhookSecretRotated"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listReportConfigs
/v1/tenants/{tenant_id}/report-configs

List the tenant's saved report definitions.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ReportConfigListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of report configs.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportConfigList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createReportConfig
/v1/tenants/{tenant_id}/report-configs

Save reporting metrics, dimensions, and grain under a tenant-unique name. The saved definition can be run again or scheduled for delivery.

parameters/TenantIdparameters/IdempotencyKeyschemas/ReportConfigCreateschemas/ReportConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReportConfigCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getReportConfig
/v1/tenants/{tenant_id}/report-configs/{report_config_id}

Get a saved report config.

schemas/ReportConfigresponses/Errorparameters/TenantIdparameters/ReportConfigId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ReportConfigId"
    }
  ],
  "responses": {
    "200": {
      "description": "The report config.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateReportConfig
/v1/tenants/{tenant_id}/report-configs/{report_config_id}

Replace a saved report config's name/metrics/dimensions/grain.

parameters/TenantIdparameters/ReportConfigIdparameters/IdempotencyKeyschemas/ReportConfigUpdateschemas/ReportConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ReportConfigId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReportConfigUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveReportConfig
/v1/tenants/{tenant_id}/report-configs/{report_config_id}/archive

Archive a saved report config.

parameters/TenantIdparameters/ReportConfigIdparameters/IdempotencyKeyschemas/ReportConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ReportConfigId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listScheduledReports
/v1/tenants/{tenant_id}/scheduled-reports

List the tenant's scheduled report deliveries.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ScheduledReportListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of scheduled reports.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReportList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createScheduledReport
/v1/tenants/{tenant_id}/scheduled-reports

Schedule delivery of a saved report to an HTTP destination. Results use the same HMAC signing convention as tenant webhooks. The signing secret is returned once in the creation response.

parameters/TenantIdparameters/IdempotencyKeyschemas/ScheduledReportCreateschemas/ScheduledReportCreatedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ScheduledReportCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created. The response includes destination_secret exactly once.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReportCreated"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getScheduledReport
/v1/tenants/{tenant_id}/scheduled-reports/{scheduled_report_id}

Read a scheduled report. The destination_secret is excluded from the response.

schemas/ScheduledReportresponses/Errorparameters/TenantIdparameters/ScheduledReportId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ScheduledReportId"
    }
  ],
  "responses": {
    "200": {
      "description": "The scheduled report.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateScheduledReport
/v1/tenants/{tenant_id}/scheduled-reports/{scheduled_report_id}

Update a scheduled report's cadence or destination URL.

parameters/TenantIdparameters/ScheduledReportIdparameters/IdempotencyKeyschemas/ScheduledReportUpdateschemas/ScheduledReportresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ScheduledReportId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ScheduledReportUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveScheduledReport
/v1/tenants/{tenant_id}/scheduled-reports/{scheduled_report_id}/archive

Archive a scheduled report (lifecycle; stops it from ever being due again).

parameters/TenantIdparameters/ScheduledReportIdparameters/IdempotencyKeyschemas/ScheduledReportresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ScheduledReportId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runScheduledReport
/v1/tenants/{tenant_id}/scheduled-reports/{scheduled_report_id}/run

Run a saved report immediately, regardless of next_run_at, and send the signed result to its destination_url. The query uses the same execution as reports/run. A successful delivery updates last_run_at and next_run_at.

parameters/TenantIdparameters/ScheduledReportIdparameters/IdempotencyKeyschemas/ScheduledReportRunResultresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ScheduledReportId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Delivery attempt result.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReportRunResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPlatforms
/v1/platforms

List the shared device and app-store platform catalog used by App.platform_id and app-store URL lookups. This catalog is available across tenants.

parameters/Limitparameters/Cursorschemas/PlatformListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "The platform catalog, name-sorted.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlatformList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listInventoryDomains
/v1/tenants/{tenant_id}/inventory-domains

List the tenant's web-domain inventory.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/InventoryDomainListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "publisher_id",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Only domains owned by this publisher."
    }
  ],
  "responses": {
    "200": {
      "description": "A page of inventory domains.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InventoryDomainList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createInventoryDomain
/v1/tenants/{tenant_id}/inventory-domains

Create a web-domain inventory record (floor, cost model, categories, ads.txt location).

parameters/TenantIdparameters/IdempotencyKeyschemas/InventoryDomainCreateschemas/InventoryDomainresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/InventoryDomainCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InventoryDomain"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getInventoryDomainStatusCounts
/v1/tenants/{tenant_id}/inventory-domains/status-counts

Per-status row counts for inventory domains.

schemas/StatusCountsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Counts keyed by status.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StatusCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET exportInventoryDomainsCsv
/v1/tenants/{tenant_id}/inventory-domains/csv

Export every non-archived inventory domain as CSV. The header is the exact header importInventoryDomainsCsv accepts, so an export → edit → import round trip is lossless.

responses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "CSV document.",
      "content": {
        "text/csv": {
          "schema": {
            "type": "string"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST importInventoryDomainsCsv
/v1/tenants/{tenant_id}/inventory-domains/csv-import

Import inventory domains from CSV (header hostname,publisher_id,site_name,ads_txt_url, floor,cost_type,cost_value,categories,keywords). Rows keyed by hostname upsert: an existing hostname is updated, a new one created. dry_run reports what would happen without persisting anything. Per-row failures never abort the batch.

parameters/TenantIdparameters/IdempotencyKeyschemas/CsvImportRequestschemas/CsvImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CsvImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row outcome.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CsvImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getInventoryDomain
/v1/tenants/{tenant_id}/inventory-domains/{inventory_domain_id}

Get one inventory domain.

schemas/InventoryDomainresponses/Errorparameters/TenantIdparameters/InventoryDomainId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InventoryDomainId"
    }
  ],
  "responses": {
    "200": {
      "description": "The inventory domain.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InventoryDomain"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateInventoryDomain
/v1/tenants/{tenant_id}/inventory-domains/{inventory_domain_id}

Update an inventory domain. Omitted fields retain their stored values.

parameters/TenantIdparameters/InventoryDomainIdparameters/IdempotencyKeyschemas/InventoryDomainUpdateschemas/InventoryDomainresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InventoryDomainId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/InventoryDomainUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InventoryDomain"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST archiveInventoryDomain
/v1/tenants/{tenant_id}/inventory-domains/{inventory_domain_id}/archive

Archive an inventory domain.

parameters/TenantIdparameters/InventoryDomainIdparameters/IdempotencyKeyschemas/InventoryDomainresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/InventoryDomainId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Archived.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/InventoryDomain"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET exportAppsCsv
/v1/tenants/{tenant_id}/apps/csv

Export every non-archived app as CSV (header bundle_id,store_id,name,platform,domain, language,store_urls,categories,max_ad_duration). Lossless round trip with importAppsCsv.

responses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "CSV document.",
      "content": {
        "text/csv": {
          "schema": {
            "type": "string"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST importAppsCsv
/v1/tenants/{tenant_id}/apps/csv-import

Import apps from CSV. Rows keyed by bundle_id (or store_id when bundle_id is empty) upsert; platform is a platform catalog name (GET /v1/platforms); store_urls and categories are pipe-separated. dry_run validates without persisting.

parameters/TenantIdparameters/IdempotencyKeyschemas/CsvImportRequestschemas/CsvImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CsvImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row outcome.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CsvImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST lookupAppStoreUrl
/v1/tenants/{tenant_id}/apps/store-lookup

Look up app metadata from a supported public app-store URL. The platform and store ID are parsed from the URL; name, bundle, and categories are fetched when the store provides a public lookup API. HTML pages are not scraped. Nothing is saved; pass the result to createApp or importAppsCsv.

schemas/StoreLookupRequestschemas/StoreLookupResultresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/StoreLookupRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Parsed / resolved metadata.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StoreLookupResult"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listApiKeys
/v1/tenants/{tenant_id}/api-keys

List API key prefixes, roles, scopes, and status for the tenant. Key secrets are excluded.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ApiKeyListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of API keys.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ApiKeyList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createApiKey
/v1/tenants/{tenant_id}/api-keys

Mint a tenant API key granting one or more tenant roles (optionally bound to one publisher or advertiser for persona roles). Only the SHA-256 hash is stored; the plaintext secret is returned exactly once in the create response.

parameters/TenantIdparameters/IdempotencyKeyschemas/ApiKeyCreateschemas/ApiKeyCreatedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ApiKeyCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created. The response includes secret exactly once.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ApiKeyCreated"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getApiKey
/v1/tenants/{tenant_id}/api-keys/{api_key_id}

Get one API key's metadata.

schemas/ApiKeyresponses/Errorparameters/TenantIdparameters/ApiKeyId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ApiKeyId"
    }
  ],
  "responses": {
    "200": {
      "description": "The API key (no secret).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ApiKey"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST revokeApiKey
/v1/tenants/{tenant_id}/api-keys/{api_key_id}/revoke

Revoke an API key. Revocation is immediate and permanent; the row is kept for audit.

parameters/TenantIdparameters/ApiKeyIdparameters/IdempotencyKeyschemas/ApiKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ApiKeyId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "200": {
      "description": "Revoked (idempotent).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ApiKey"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST rotateApiKey
/v1/tenants/{tenant_id}/api-keys/{api_key_id}/rotate

Create a successor API key with the same name, roles, persona binding, and scopes. Its plaintext secret is returned once. The previous key expires after the specified grace period. Only ACTIVE, unexpired keys can rotate; other keys return 409 CONFLICT. A retry with the same idempotency key and payload returns the same successor with an empty secret. A changed payload returns 409 idempotency_key_reused.

parameters/TenantIdparameters/ApiKeyIdparameters/IdempotencyKeyschemas/ApiKeyRotatedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ApiKeyId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    },
    {
      "name": "grace",
      "in": "query",
      "required": false,
      "description": "How long the previous key keeps authenticating after the rotation, as a duration string such as `24h`, `90m` or `2h30m`. Omitted = the platform default grace; a value above the platform maximum is rejected 400.\n",
      "schema": {
        "type": "string",
        "maxLength": 32
      }
    }
  ],
  "responses": {
    "201": {
      "description": "Rotated. The response includes the successor's secret exactly once.",
      "headers": {
        "Cache-Control": {
          "description": "Always `no-store` — the secret must never be served from a cache.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ApiKeyRotated"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPublisherPlacements
/v1/tenants/{tenant_id}/publishers/{publisher_id}/placements

Placements owned by this publisher (Placement.publisher_id). A publisher-role actor may only call this for its bound publisher_id.

parameters/TenantIdparameters/PublisherIdparameters/Limitparameters/Cursorschemas/PlacementListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of placements.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PlacementList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPublisherReportSummary
/v1/tenants/{tenant_id}/publishers/{publisher_id}/report-summary

Publisher portal dashboard tile: requests / impressions / fills / net revenue / publisher payout for this publisher over the trailing window, from the reporting semantic layer with the publisher filter injected server-side.

parameters/TenantIdparameters/PublisherIdschemas/PublisherReportSummaryresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "name": "days",
      "in": "query",
      "required": false,
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 90,
        "default": 7
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Publisher-scoped KPI summary.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PublisherReportSummary"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runPublisherReport
/v1/tenants/{tenant_id}/publishers/{publisher_id}/reports/run

Run a report using ReportRunRequest with the publisher's public_id enforced as a server-side filter. A supplied publisher filter naming another publisher returns BAD_INPUT.

schemas/ReportRunRequestschemas/ReportRunResponseresponses/Errorparameters/TenantIdparameters/PublisherId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReportRunRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Compiled (and, when a warehouse is configured, executed) report.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportRunResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPublisherReportConfigs
/v1/tenants/{tenant_id}/publishers/{publisher_id}/report-configs

Saved report definitions scoped to this publisher (ReportConfig.publisher_id).

parameters/TenantIdparameters/PublisherIdparameters/Limitparameters/Cursorschemas/ReportConfigListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of report configs.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportConfigList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createPublisherReportConfig
/v1/tenants/{tenant_id}/publishers/{publisher_id}/report-configs

Save a publisher-scoped report definition. The stored config carries publisher_id; every run (ad hoc or scheduled) injects the publisher filter.

parameters/TenantIdparameters/PublisherIdparameters/IdempotencyKeyschemas/ReportConfigCreateschemas/ReportConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReportConfigCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReportConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPublisherScheduledReports
/v1/tenants/{tenant_id}/publishers/{publisher_id}/scheduled-reports

Scheduled deliveries over this publisher's report configs.

parameters/TenantIdparameters/PublisherIdparameters/Limitparameters/Cursorschemas/ScheduledReportListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of scheduled reports.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReportList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createPublisherScheduledReport
/v1/tenants/{tenant_id}/publishers/{publisher_id}/scheduled-reports

Schedule delivery of one of this publisher's report configs. report_config_id must be a config scoped to the same publisher; the schedule inherits the scope.

parameters/TenantIdparameters/PublisherIdparameters/IdempotencyKeyschemas/ScheduledReportCreateschemas/ScheduledReportCreatedresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ScheduledReportCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created. The response includes destination_secret exactly once.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ScheduledReportCreated"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPublisherPayoutStatements
/v1/tenants/{tenant_id}/publishers/{publisher_id}/payout-statements

List publisher payout statements, newest period first.

parameters/TenantIdparameters/PublisherIdparameters/Limitparameters/Cursorschemas/PublisherPayoutStatementListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of statements.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PublisherPayoutStatementList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST generatePublisherPayoutStatement
/v1/tenants/{tenant_id}/publishers/{publisher_id}/payout-statements

Close a period for this publisher: aggregate the reporting layer's publisher_payout leg over [period_start, period_end), apply the signed adjustment, and issue the statement through the configured payout provider. Idempotent per (publisher, period): a repeated close returns the existing statement.

parameters/TenantIdparameters/PublisherIdparameters/IdempotencyKeyschemas/PublisherPayoutStatementGenerateschemas/PublisherPayoutStatementresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PublisherPayoutStatementGenerate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Statement issued (or the existing one for that period).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PublisherPayoutStatement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPublisherPayoutStatement
/v1/tenants/{tenant_id}/publishers/{publisher_id}/payout-statements/{statement_id}

Get one payout statement.

schemas/PublisherPayoutStatementresponses/Errorparameters/TenantIdparameters/PublisherIdparameters/StatementId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/StatementId"
    }
  ],
  "responses": {
    "200": {
      "description": "The statement.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PublisherPayoutStatement"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET exportPublisherPayoutStatementCsv
/v1/tenants/{tenant_id}/publishers/{publisher_id}/payout-statements/{statement_id}/csv

Download a publisher payout statement as CSV.

responses/Errorparameters/TenantIdparameters/PublisherIdparameters/StatementId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/PublisherId"
    },
    {
      "$ref": "#/components/parameters/StatementId"
    }
  ],
  "responses": {
    "200": {
      "description": "CSV document.",
      "content": {
        "text/csv": {
          "schema": {
            "type": "string"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getTenantCells
/v1/operator/tenants/{tenant_id}/cells

Read the tenant's home cell and serving cells. Operator access required.

schemas/TenantCellsresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "The tenant's cell assignment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantCells"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT setTenantCells
/v1/operator/tenants/{tenant_id}/cells

Replace a tenant's cell assignment: the home cell (control-plane residency) and the full serving-cell set (the home cell is always a serving cell; it is added when omitted). The next compile of every affected cell carries or drops the tenant. Operator only.

parameters/TenantIdparameters/IdempotencyKeyschemas/TenantCellsUpdateschemas/TenantCellsresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TenantCellsUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored assignment.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantCells"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCell
/v1/operator/cells/{cell_id}

Read a cell's registry record. Operator access required.

schemas/Cellresponses/Errorparameters/CellId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/CellId"
    }
  ],
  "responses": {
    "200": {
      "description": "The cell.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Cell"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listCellTenants
/v1/operator/cells/{cell_id}/tenants

List tenants assigned to serve in the cell, sorted by tenant ID. This is the tenant set included in the cell's next serving-plan compile. Operator access required.

parameters/CellIdparameters/Limitparameters/Cursorschemas/TenantCellRefListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/CellId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of tenant references.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/TenantCellRefList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listDemandPartnerDomainApprovals
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/domain-approvals

A partner's site-domain approvals (demand_partner_domain_approval), sorted by domain.

parameters/TenantIdparameters/DemandPartnerIdparameters/Limitparameters/Cursorschemas/ApprovalStatusschemas/DomainApprovalListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
        "$ref": "#/components/schemas/ApprovalStatus"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of domain approvals.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DomainApprovalList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT setDemandPartnerDomainApproval
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/domain-approvals/{domain}

Upsert one site-domain approval for the partner (PENDING | APPROVED | REJECTED). APPROVED rows project onto the plan (DemandPartner.approved_domains) at the next compile.

parameters/TenantIdparameters/DemandPartnerIdparameters/ApprovalDomainparameters/IdempotencyKeyschemas/DomainApprovalUpdateschemas/DomainApprovalresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/ApprovalDomain"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DomainApprovalUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The stored approval.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DomainApproval"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
DELETE deleteDemandPartnerDomainApproval
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/domain-approvals/{domain}

Remove one site-domain approval (the domain reverts to "no record").

parameters/TenantIdparameters/DemandPartnerIdparameters/ApprovalDomainparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/ApprovalDomain"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Removed (or never existed)."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getDemandPartnerApprovalCounts
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/approval-counts

Read per-partner approval counts by status for app bundles and site domains.

schemas/ApprovalCountsresponses/Errorparameters/TenantIdparameters/DemandPartnerId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    }
  ],
  "responses": {
    "200": {
      "description": "Counts.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ApprovalCounts"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET exportDemandPartnerApprovalsCsv
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/approvals/csv

Export a partner's approvals as CSV (header kind,key,status,note): one row per app bundle approval (kind=bundle, key=bundle id) and per site-domain approval (kind=domain, key=domain). Lossless round trip with importDemandPartnerApprovalsCsv.

responses/Errorparameters/TenantIdparameters/DemandPartnerId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    }
  ],
  "responses": {
    "200": {
      "description": "CSV document.",
      "content": {
        "text/csv": {
          "schema": {
            "type": "string"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST importDemandPartnerApprovalsCsv
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/approvals/csv-import

Import approvals from CSV (header kind,key,status,note). kind=bundle rows upsert the app_route_approval row of the tenant's app with that bundle id (an unknown bundle is an error row); kind=domain rows upsert demand_partner_domain_approval. dry_run validates without persisting.

parameters/TenantIdparameters/DemandPartnerIdparameters/IdempotencyKeyschemas/CsvImportRequestschemas/CsvImportResponseresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CsvImportRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Per-row outcome.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CsvImportResponse"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getCrawlerConfig
/v1/tenants/{tenant_id}/supply-transparency/crawler-config

Read the tenant's ads.txt and app-ads.txt crawler settings. Returns platform defaults when no settings have been saved.

schemas/CrawlerConfigresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Effective crawler config.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CrawlerConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateCrawlerConfig
/v1/tenants/{tenant_id}/supply-transparency/crawler-config

Upsert the tenant's crawler tunables (partial update by presence).

parameters/TenantIdparameters/IdempotencyKeyschemas/CrawlerConfigUpdateschemas/CrawlerConfigresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CrawlerConfigUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Effective crawler config after the update.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CrawlerConfig"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listPartnerSellersImports
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/sellers-imports

Imports of the partner's sellers.json (partner_sellers_import), newest first.

parameters/TenantIdparameters/DemandPartnerIdparameters/Limitparameters/Cursorschemas/PartnerSellersImportListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    }
  ],
  "responses": {
    "200": {
      "description": "A page of imports (without rows).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PartnerSellersImportList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getPartnerSellersImport
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/sellers-imports/{import_id}

One sellers.json import with its parsed rows and compliance verdicts.

schemas/PartnerSellersImportresponses/Errorparameters/TenantIdparameters/DemandPartnerIdparameters/PartnerSellersImportId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/PartnerSellersImportId"
    }
  ],
  "responses": {
    "200": {
      "description": "The import.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PartnerSellersImport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST runPartnerSellersImport
/v1/tenants/{tenant_id}/demand-partners/{demand_partner_id}/sellers-import/run

Create a PENDING sellers.json import with a source URL. The daily import job fetches, parses, and checks the document, then updates its status, counts, and rows. Returns the created import record.

parameters/TenantIdparameters/DemandPartnerIdparameters/IdempotencyKeyschemas/PartnerSellersImportRunRequestschemas/PartnerSellersImportresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/DemandPartnerId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PartnerSellersImportRunRequest"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "The recorded import (status PENDING until the tick runs it).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PartnerSellersImport"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET listContentPrograms
/v1/tenants/{tenant_id}/content-programs

A tenant's program-guide entries (content_program), sorted by id; filter by provider / channel.

parameters/TenantIdparameters/Limitparameters/Cursorschemas/ContentProgramListresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/Limit"
    },
    {
      "$ref": "#/components/parameters/Cursor"
    },
    {
      "name": "provider",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "channel",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "A page of programs.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ContentProgramList"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST createContentProgram
/v1/tenants/{tenant_id}/content-programs

Add a program-guide entry; (provider, external_id) is unique per tenant (409 on a duplicate).

parameters/TenantIdparameters/IdempotencyKeyschemas/ContentProgramCreateschemas/ContentProgramresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ContentProgramCreate"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "Created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ContentProgram"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getContentDictionary
/v1/tenants/{tenant_id}/content-programs/dictionary

List distinct genres, keywords, providers, and channels in the tenant's program guide, with program counts. These values can be used in targeting rules and the content_keyword and content_genre report dimensions.

schemas/ContentDictionaryresponses/Errorparameters/TenantId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    }
  ],
  "responses": {
    "200": {
      "description": "Dictionary.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ContentDictionary"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
GET getContentProgram
/v1/tenants/{tenant_id}/content-programs/{program_id}

One program-guide entry.

schemas/ContentProgramresponses/Errorparameters/TenantIdparameters/ContentProgramId

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ContentProgramId"
    }
  ],
  "responses": {
    "200": {
      "description": "The program.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ContentProgram"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
PUT updateContentProgram
/v1/tenants/{tenant_id}/content-programs/{program_id}

Partial update by presence; arrays present replace the whole set.

parameters/TenantIdparameters/ContentProgramIdparameters/IdempotencyKeyschemas/ContentProgramUpdateschemas/ContentProgramresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ContentProgramId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ContentProgramUpdate"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "The updated program.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ContentProgram"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
DELETE deleteContentProgram
/v1/tenants/{tenant_id}/content-programs/{program_id}

Remove a program-guide entry.

parameters/TenantIdparameters/ContentProgramIdparameters/IdempotencyKeyresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "$ref": "#/components/parameters/TenantId"
    },
    {
      "$ref": "#/components/parameters/ContentProgramId"
    },
    {
      "$ref": "#/components/parameters/IdempotencyKey"
    }
  ],
  "responses": {
    "204": {
      "description": "Removed."
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ]
}
POST paymentProviderWebhook
/v1/webhooks/payment/{provider}

Receive a payment-provider event for a successful or failed payment, refund, or dispute. Authentication uses the provider's signature header and secret to verify the raw request body before parsing; missing or invalid signatures return 401 UNAUTHORIZED. Bearer credentials and API keys are not used. Each provider and external_id pair is recorded once and applied to its invoice. Successful payments mark invoices PAID; failed charges advance payment collection. Duplicate events return 200 with duplicate: true and make no changes. The provider should retry 5xx responses. Idempotency-Key is not required.

schemas/PaymentProviderEventschemas/PaymentWebhookAckresponses/Error

Parameters, request and responses

{
  "parameters": [
    {
      "name": "provider",
      "in": "path",
      "required": true,
      "description": "Registered payment-provider adapter key (libs/billing payment seam).",
      "schema": {
        "type": "string",
        "pattern": "^[a-z][a-z0-9_]{1,31}$"
      }
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PaymentProviderEvent"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Event recorded (or recognised as a redelivery).",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PaymentWebhookAck"
          }
        }
      }
    },
    "default": {
      "$ref": "#/components/responses/Error"
    }
  },
  "security": []
}

Component definitions

securitySchemes

bearerAuth

{
  "type": "http",
  "scheme": "bearer",
  "description": "Opaque console session (`rt_sess_…`) or a signed JWT (libs/authz)."
}
apiKeyAuth

{
  "type": "apiKey",
  "in": "header",
  "name": "X-Riptide-Api-Key",
  "description": "Durable tenant / operator API key minted by createApiKey (`rt_key_…`) or a bootstrap key from RIPTIDE_API_KEYS_JSON. Resolved by services/console rbacMiddleware.\n"
}

parameters

TenantId

{
  "description": "The tenant the resource belongs to (the path is the tenant boundary; a body never names a tenant).",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "tenant_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
PublisherId

{
  "description": "Publisher id (uuid; the public id is a separate, human-chosen key).",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "publisher_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
InviteId

{
  "description": "Invite id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "invite_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
DeliveryAlertEventId

{
  "description": "Delivery alert event id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "event_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ReconciliationStatementId

{
  "description": "Reconciliation statement id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "statement_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ReconciliationReportId

{
  "description": "Reconciliation report id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "report_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
PlacementId

{
  "description": "Placement id (uuid; the public id is the tag key).",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "placement_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
CampaignOrderId

{
  "description": "Campaign order id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "campaign_order_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
LineItemId

{
  "description": "Line item id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "line_item_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
CreativeId

{
  "description": "Creative id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "creative_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
CreativeMediaUploadId

{
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "upload_id",
  "in": "path",
  "required": true,
  "description": "Media upload record id (SR-307), minted by createCreativeMediaUpload.",
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
AudienceId

{
  "description": "Audience id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "audience_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
DemandPartnerId

{
  "description": "Demand partner id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "demand_partner_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
AppId

{
  "description": "App id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "app_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
AppLookupCacheKey

{
  "example": "acme-pub%7Ccom.example.app",
  "name": "cache_key",
  "in": "path",
  "required": true,
  "description": "App-resolution cache key (publisher_public_id|bundle_id). Path-encode `|` as `%7C`.\n",
  "schema": {
    "type": "string",
    "minLength": 1
  }
}
VerificationVendorConfigId

{
  "description": "Verification vendor configuration id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "config_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
IpListId

{
  "description": "IP list id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "list_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
BidModifierId

{
  "description": "Bid modifier id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "modifier_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
CustomListId

{
  "description": "Custom list id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "list_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
CreativeTemplateId

{
  "description": "Creative template id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "template_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
DeliveryExperimentId

{
  "description": "Delivery experiment id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "experiment_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
DeliveryAlertRuleId

{
  "description": "Delivery alert rule id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "rule_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ItemCatalogId

{
  "description": "Item catalog id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "catalog_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ExportDestinationId

{
  "description": "Export destination id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "destination_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ExportJobId

{
  "description": "Export job id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "job_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
SupplyDocumentCheckId

{
  "description": "Supply document check id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "check_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
SupplyDocumentSnapshotId

{
  "description": "Supply document snapshot id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "snapshot_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
DemandRouteId

{
  "description": "Demand route id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "demand_route_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
DealId

{
  "description": "Deal id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "deal_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
MarketplaceId

{
  "description": "Marketplace id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "marketplace_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
MarketplaceListingId

{
  "description": "Marketplace listing id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "listing_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
AdvertiserId

{
  "description": "Advertiser id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "advertiser_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
FeeScheduleId

{
  "description": "Fee schedule id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "fee_schedule_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ReportConfigId

{
  "description": "Report config id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "report_config_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ScheduledReportId

{
  "description": "Scheduled report id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "scheduled_report_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
InventoryDomainId

{
  "description": "Inventory domain id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "inventory_domain_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ApiKeyId

{
  "description": "API key id (the row, never the secret).",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "api_key_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
StatementId

{
  "description": "Statement id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "statement_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
UserId

{
  "description": "User id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "user_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
SealingKeyId

{
  "example": "acme-2026-09",
  "name": "key_id",
  "in": "path",
  "required": true,
  "description": "Opaque sealing key id embedded in sealed payloads (not the row uuid).",
  "schema": {
    "type": "string",
    "minLength": 1
  }
}
WebhookSubscriptionId

{
  "description": "Webhook subscription id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "webhook_subscription_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
WebhookDeliveryId

{
  "description": "Webhook delivery id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "webhook_delivery_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
Limit

{
  "example": 100,
  "name": "limit",
  "in": "query",
  "required": false,
  "description": "Page size (default 100, max 1000); larger values are clamped to 1000.",
  "schema": {
    "type": "integer",
    "minimum": 1,
    "maximum": 1000,
    "default": 100
  }
}
Cursor

{
  "example": "next_01J9Z3Q7R8S9T0V1W2X3Y4Z5A6",
  "name": "cursor",
  "in": "query",
  "required": false,
  "description": "Opaque keyset cursor from the previous page's `next_cursor`. Clients must not construct or parse it; a cursor is only valid for the operation (and filters) that issued it and a malformed one is answered 400 BAD_INPUT.\n",
  "schema": {
    "type": "string"
  }
}
CellId

{
  "description": "Cell id as registered by the operator (for example the region and ordinal).",
  "example": "cell-us-east-1",
  "name": "cell_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "minLength": 1
  }
}
ApprovalDomain

{
  "example": "publisher.example",
  "name": "domain",
  "in": "path",
  "required": true,
  "description": "Site domain (lower-case, no scheme) the approval is keyed by.",
  "schema": {
    "type": "string",
    "minLength": 4,
    "maxLength": 253
  }
}
PartnerSellersImportId

{
  "description": "Partner sellers.json import id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "import_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
ContentProgramId

{
  "description": "Content program id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "program_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
IdempotencyKey

{
  "example": "5f0b4c1e-6d7a-4b8c-9d0e-1f2a3b4c5d6e",
  "name": "Idempotency-Key",
  "in": "header",
  "required": true,
  "description": "Client-chosen key that makes the mutation safe to retry. The console records a hash of the request payload under (actor, method, path, key): a replay with an identical payload returns the original response, a replay with a different payload is answered 409 CONFLICT (`hint: idempotency_key_reused`).\n",
  "schema": {
    "type": "string",
    "minLength": 1,
    "maxLength": 200
  }
}
InvoiceId

{
  "description": "Invoice id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "invoice_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
AgentIdentityId

{
  "description": "Agent identity id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "agent_identity_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
PrivacyRequestId

{
  "description": "Privacy request id.",
  "example": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
  "name": "privacy_request_id",
  "in": "path",
  "required": true,
  "schema": {
    "type": "string",
    "format": "uuid"
  }
}
UserKey

{
  "example": "u_9f2c1e7a",
  "name": "user_key",
  "in": "path",
  "required": true,
  "description": "Opaque first-party user key (design 33). Not a raw email/phone; max 256 chars; alphanumeric plus . _ : @ + - (no whitespace or path separators).\n",
  "schema": {
    "type": "string",
    "minLength": 1,
    "maxLength": 256,
    "pattern": "^[A-Za-z0-9._:@+-]{1,256}$"
  }
}

responses

Error

schemas/Error

{
  "description": "Typed error.",
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/Error"
      }
    }
  }
}

schemas

Error

schemas/FieldError

{
  "example": {
    "code": "BAD_INPUT",
    "message": "name is required",
    "hint": "missing_field:name",
    "request_id": "req_01J9Z3Q7R8S9T0V1W2X3Y4Z5A6",
    "details": [
      {
        "field": "name",
        "code": "required",
        "message": "name is required"
      }
    ]
  },
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "string",
      "enum": [
        "BAD_INPUT",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "NOT_ENTITLED",
        "NOT_FOUND",
        "LIMITING",
        "TIMEOUT",
        "CONFLICT",
        "INTERNAL"
      ]
    },
    "message": {
      "type": "string"
    },
    "hint": {
      "type": "string",
      "description": "A stable, dotted, machine-actionable code a client can branch on programmatically (e.g. \"missing_field:name\", \"cross_tenant_denied\", \"retryable\") without parsing `message` — see docs/spec/api-fundamentals.md and libs/apierrors. Optional; not every error carries one yet (a documented, ratcheting rollout, not a contract requirement).\n"
    },
    "request_id": {
      "type": "string"
    },
    "details": {
      "type": "array",
      "description": "Per-field errors for BAD_INPUT responses (UX-41); absent when the error is not field-scoped.",
      "items": {
        "$ref": "#/components/schemas/FieldError"
      }
    }
  }
}
FieldError

{
  "type": "object",
  "required": [
    "field",
    "message"
  ],
  "properties": {
    "field": {
      "type": "string",
      "description": "JSON pointer-ish property path (e.g. `name`, `stitch.max_ads`)."
    },
    "code": {
      "type": "string",
      "description": "Stable machine code (`required`, `invalid`, `conflict`)."
    },
    "message": {
      "type": "string"
    }
  }
}
AuditLogEnvelope

{
  "type": "object",
  "description": "One immutable AuditEnvelope row from audit_log, exposed read-only for operability. The before_json and after_json fields are JSON strings to match proto/riptide/agent/v1's AuditEnvelope contract and preserve arbitrary resource payloads exactly.\n",
  "required": [
    "id",
    "tenant_id",
    "actor_label",
    "action",
    "rationale",
    "model_id",
    "model_version",
    "before_json",
    "after_json",
    "outcome",
    "at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "actor_label": {
      "type": "string",
      "description": "Opaque actor label for API-key/JWT/operator callers; empty when only actor_agent_id is populated."
    },
    "actor_agent_id": {
      "type": "string",
      "format": "uuid",
      "description": "Registered agent identity id when the audit row was written by an agent identity."
    },
    "action": {
      "type": "string"
    },
    "rationale": {
      "type": "string"
    },
    "model_id": {
      "type": "string"
    },
    "model_version": {
      "type": "string"
    },
    "before_json": {
      "type": "string"
    },
    "after_json": {
      "type": "string"
    },
    "outcome": {
      "type": "string"
    },
    "at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
AuditLogList

schemas/AuditLogEnvelope

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AuditLogEnvelope"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Opaque cursor for the next page; absent when no more rows are available."
    }
  }
}
LifecycleStatus

{
  "type": "string",
  "enum": [
    "ACTIVE",
    "INACTIVE",
    "ARCHIVED"
  ]
}
GeoReferenceLevel

{
  "type": "string",
  "description": "Geo dictionary hierarchy level (libs/enrich GeoLevel*), country → region → metro → city.",
  "enum": [
    "country",
    "region",
    "metro",
    "city"
  ],
  "x-enum-varnames": [
    "GeoReferenceLevelCountry",
    "GeoReferenceLevelRegion",
    "GeoReferenceLevelMetro",
    "GeoReferenceLevelCity"
  ]
}
GeoDictEntry

schemas/GeoReferenceLevel

{
  "type": "object",
  "description": "One distinct value of the loaded dataset at a level (libs/enrich.GeoDictEntry). country / region are set for every level below country; metro is the metro code at the metro level and, for a city, the metro its rows fall under (absent = none). code is the numeric value a targeting rule stores (metro code at the metro level, the stable city code at the city level; absent otherwise); name is the display label.\n",
  "required": [
    "level",
    "country",
    "name"
  ],
  "properties": {
    "level": {
      "$ref": "#/components/schemas/GeoReferenceLevel"
    },
    "country": {
      "type": "string",
      "description": "ISO 3166-1 alpha-2 country code."
    },
    "region": {
      "type": "string",
      "description": "Region code within the country."
    },
    "metro": {
      "type": "integer",
      "format": "int32",
      "description": "Metro (DMA) code."
    },
    "code": {
      "type": "integer",
      "format": "int32",
      "description": "Numeric value a targeting rule stores for this entry."
    },
    "name": {
      "type": "string",
      "description": "Display label (country code, region code, metro code as text, or city name)."
    }
  }
}
GeoReferenceDataset

{
  "type": "object",
  "description": "Which dataset version the page's labels came from, so a picker can show it.",
  "required": [
    "version",
    "loaded_at",
    "rows"
  ],
  "properties": {
    "version": {
      "type": "string",
      "description": "Dataset identifier: blob:<sha256 prefix>/<rows>."
    },
    "loaded_at": {
      "type": "string",
      "format": "date-time"
    },
    "rows": {
      "type": "integer",
      "description": "IP ranges in the loaded dataset."
    }
  }
}
GeoReferencePage

schemas/GeoDictEntryschemas/GeoReferenceDataset

{
  "type": "object",
  "description": "One page of dictionary entries (docs/spec/api-fundamentals.md \"Cursor pagination\").",
  "required": [
    "items",
    "total",
    "dataset"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/GeoDictEntry"
      }
    },
    "total": {
      "type": "integer",
      "description": "Entries matching the query across every page."
    },
    "next_cursor": {
      "type": "string",
      "description": "Opaque cursor for the next page; absent on the last page."
    },
    "dataset": {
      "$ref": "#/components/schemas/GeoReferenceDataset"
    }
  }
}
AudioToVideoConfig

{
  "type": "object",
  "description": "One level of the audio-to-video hierarchical configuration (docs/design/11-stitching.md's tenant -> publisher -> brand -> platform-default hierarchy), mirrored field-for-field from plan.v1.AudioToVideoConfig. Enabling requires the tenant `audio_to_video` entitlement.\n",
  "properties": {
    "id": {
      "type": "string"
    },
    "version": {
      "type": "integer",
      "description": "Bump to invalidate cache entries rendered under a prior config."
    },
    "background_url": {
      "type": "string",
      "description": "The visual composited behind the audio."
    },
    "width": {
      "type": "integer",
      "minimum": 1
    },
    "height": {
      "type": "integer",
      "minimum": 1
    }
  }
}
Tenant

schemas/LifecycleStatusschemas/RetentionTierschemas/AudioToVideoConfigschemas/Brandingschemas/Entitlementschemas/GovernorLimitschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "required": [
    "id",
    "name",
    "slug",
    "region",
    "cell_id",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "slug": {
      "type": "string"
    },
    "region": {
      "type": "string"
    },
    "cell_id": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "retention_tier": {
      "readOnly": true,
      "description": "Telemetry retention tier every event of the tenant is stamped with at publish (SR-1239b; Event.retention_tier): derived from the plan's telemetry tier — full → extended, sampled → standard, minimal → basic, unspecified → standard. The event store's TTL reads it.\n",
      "allOf": [
        {
          "$ref": "#/components/schemas/RetentionTier"
        }
      ]
    },
    "sandbox": {
      "type": "boolean",
      "readOnly": true,
      "description": "Sandbox tenant (SR-1240): accepts loadSampleData, never bills, and is labelled as such in the console."
    },
    "sample_data_loaded_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "readOnly": true,
      "description": "When loadSampleData last completed; null when never loaded."
    },
    "timezone": {
      "type": "string",
      "description": "IANA time zone for the console's default reporting / flight display (UX-41). Defaults to UTC; serving day-buckets stay UTC."
    },
    "default_delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400,
      "description": "Tenant default supply-side delivery window (seconds); see delivery-timing.md."
    },
    "audio_to_video": {
      "$ref": "#/components/schemas/AudioToVideoConfig"
    },
    "audio_to_video_by_brand": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/AudioToVideoConfig"
      },
      "description": "Per-advertiser-domain (\"brand\") audio-to-video override, keyed by advertiser domain (auction.Bid.AdvertiserDomain). Consulted after tenant, before the platform default.\n"
    },
    "branding": {
      "$ref": "#/components/schemas/Branding"
    },
    "entitlements": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Entitlement"
      },
      "description": "Feature gates for this tenant (docs/glossary.md: `ssp`|`dsp`|`ad_server` plus sub-features like `warm_pool`|`stitch`|`audio_to_video`|`verification`|`deals`) — mirrors plan.v1.Tenant.entitlements / the `tenant_entitlement` table. The console (P3-04) uses the `ssp`/`dsp`/`ad_server` features to show/hide its three modules.\n"
    },
    "settlement_currency": {
      "type": "string",
      "description": "ISO 4217 settlement currency for bid normalization. Empty means process-level FX config applies; RIPTIDE_FX_SETTLEMENT_CURRENCY_JSON remains an emergency override.\n"
    },
    "governor": {
      "$ref": "#/components/schemas/GovernorLimit"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "supply_contact_email": {
      "type": "string",
      "description": "Contact email published in the tenant's sellers.json `contact_email` field (IAB sellers.json 1.0). Empty means the document omits the field.\n"
    },
    "creative_auto_approve": {
      "type": "boolean",
      "default": true,
      "description": "Creative review policy (design 31 §2C). True keeps auto-approve when the pipeline reaches READY; false requires manual approve/reject via reviewCreative, and material content changes re-audit (APPROVED resets to PENDING).\n"
    },
    "sanctioned_countries": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 2,
        "maxLength": 2
      },
      "description": "ISO-3166 alpha-2 countries this tenant must never monetise (compliance gate, docs/design/08-economics.md \"Request-level gates\"): a request whose country is listed is answered no-bid with reason `sanctioned_geo` before any demand is dialed.\n"
    },
    "request_quota_per_day": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Rate-plan request quota per UTC day; 0/omitted = unlimited. serve meters accepted requests and answers `quota_exceeded` at the quota (fail-open when the meter is down).\n"
    },
    "serving_suspended": {
      "type": "boolean",
      "description": "Control-plane serving kill switch (prepaid balance exhausted / overdue rate plan): serve answers every request `serving_suspended`.\n"
    },
    "bad_input_http_errors": {
      "type": "boolean",
      "description": "Bad player input posture (SR-1217, design 09 \"Bad player input posture\"): false (default) answers malformed tag / OpenRTB input the way a player degrades gracefully (an empty VAST document on /vast, a body-less 204 on /ortb); true opts into typed 4xx errors for integration debugging.\n"
    },
    "home_cell_id": {
      "type": "string",
      "description": "Cell that owns the tenant's control-plane residency (SR-1221, design 16 \"Tenant->cell routing seam\"; tenant_cell role `home`). Read-only here; set through setTenantCells. Equals `cell_id` until the tenant is re-homed.\n"
    },
    "serving_cell_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Every cell whose serving plan carries the tenant (home included; tenant_cell roles `home` | `serving`), sorted. Read-only here; set through setTenantCells.\n"
    },
    "tag_id": {
      "type": "string",
      "description": "Certification-authority id (16 hex characters) rendered on the tenant's own ads.txt / app-ads.txt lines and as a sellers.json identifier (SR-1212, design 06 \"Supply chain\"). Empty = omitted from the documents.\n"
    },
    "contact_address": {
      "type": "string",
      "description": "Postal contact rendered into the tenant's sellers.json `contact_address` (SR-1212). Empty = omitted.\n"
    },
    "stale_plan_fail_open": {
      "type": "boolean",
      "description": "Stale-plan posture (SR-1235, design 03 \"Converge\"): true keeps serving the last-known plan past the stale ceiling (with the PlanStale alert firing) instead of the default house-only / out-of-rotation posture.\n"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
Branding

{
  "type": "object",
  "description": "A tenant's white-label identity (docs/design/01-platform.md, docs/glossary.md): the product name shown in the console/reports, and the hostnames a white-label deployment serves ads/events/user-sync from — mirrors plan.v1.Branding / the `tenant.ad_system_name`+ `serving_domain`+`event_domain`+`sync_domain` columns. `serving_domain` doubles as the console's host->tenant resolution key (P3-04's white-label hostname hook).\n",
  "properties": {
    "ad_system_name": {
      "type": "string",
      "description": "Product/brand name shown in the console UI."
    },
    "serving_domain": {
      "type": "string",
      "description": "Hostname the tenant serves ads from."
    },
    "event_domain": {
      "type": "string",
      "description": "Hostname the tenant serves tracking events from."
    },
    "sync_domain": {
      "type": "string",
      "description": "Hostname the tenant uses for user-sync."
    },
    "logo_url": {
      "type": "string",
      "description": "HTTPS URL of the console / report logo (UX-41)."
    },
    "favicon_url": {
      "type": "string",
      "description": "HTTPS URL of the console favicon."
    },
    "primary_color": {
      "type": "string",
      "pattern": "^#[0-9a-fA-F]{6}$",
      "description": "Primary brand colour (#rrggbb) applied to the console theme tokens."
    },
    "accent_color": {
      "type": "string",
      "pattern": "^#[0-9a-fA-F]{6}$",
      "description": "Accent brand colour (#rrggbb)."
    },
    "email_sender": {
      "type": "string",
      "description": "Requested From address (display name allowed) for tenant-branded mail. Magic links and invites use this mailbox only when it matches the operator's tenant-specific RIPTIDE_AUTH_EMAIL_SENDERS_JSON authorization; otherwise they use the platform mailbox with the tenant display name."
    }
  }
}
Entitlement

{
  "type": "object",
  "required": [
    "feature",
    "enabled"
  ],
  "description": "One feature gate on a tenant (plan.v1.Entitlement / `tenant_entitlement` row). `feature` is a free-form key (docs/glossary.md): `ssp`|`dsp`|`ad_server`|`warm_pool`|`stitch`| `audio_to_video`|`verification`|`deals`|`demand_rate_types` (default off — gates non-CPM demand buy rates on line items; design 32 / D51)|`roas_autobid` (default off — gates ROAS/GMV optimization_goal on line items; design 35 §6 / CP-13).\n",
  "properties": {
    "feature": {
      "type": "string",
      "minLength": 1
    },
    "enabled": {
      "type": "boolean"
    },
    "limits": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    }
  }
}
GovernorLimit

{
  "type": "object",
  "description": "Compiled admission governor for tenant-scope QPS/share-of-voice. Zero or omitted values are unlimited; share_of_voice is a decimal fraction string such as \"0.250000\".\n",
  "properties": {
    "qps": {
      "type": "integer",
      "minimum": 0
    },
    "burst": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "string",
      "pattern": "^(0(\\.\\d{1,6})?|1(\\.0{1,6})?)$"
    }
  }
}
SupplyTransparencyMode

{
  "type": "string",
  "description": "Inheritable verify-and-decide mode for ads.txt/app-ads.txt/sellers.json facts.",
  "enum": [
    "off",
    "observe",
    "require"
  ]
}
SupplyTransparencyPolicy

schemas/SupplyTransparencyMode

{
  "type": "object",
  "description": "Inheritable ads.txt/app-ads.txt/sellers.json policy. Omitted fields inherit from the next broader scope; mode=require makes failed compiled authorization facts bid-time blocking.\n",
  "properties": {
    "mode": {
      "$ref": "#/components/schemas/SupplyTransparencyMode"
    },
    "max_hops": {
      "type": "integer",
      "minimum": 0
    },
    "require_ads_txt": {
      "type": "boolean"
    },
    "require_sellers_json": {
      "type": "boolean"
    },
    "require_direct_only": {
      "type": "boolean"
    }
  }
}
SupplyDocumentKind

{
  "type": "string",
  "enum": [
    "ads_txt",
    "app_ads_txt",
    "sellers_json"
  ]
}
SupplyDocumentSubjectType

{
  "type": "string",
  "enum": [
    "publisher",
    "tenant",
    "demand_partner",
    "domain"
  ]
}
SupplyDocumentCheckStatus

{
  "type": "string",
  "enum": [
    "ok",
    "missing",
    "stale",
    "malformed",
    "unauthorized",
    "error"
  ]
}
SupplyDocumentPreview

schemas/SupplyDocumentKind

{
  "type": "object",
  "required": [
    "kind",
    "content_type",
    "content"
  ],
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/SupplyDocumentKind"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid"
    },
    "url": {
      "type": "string",
      "description": "Canonical document path or derived crawl URL for the previewed subject."
    },
    "content_type": {
      "type": "string"
    },
    "content": {
      "type": "string"
    },
    "generated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
SupplyDocumentVerifyRequest

schemas/SupplyDocumentKindschemas/SupplyDocumentSubjectType

{
  "type": "object",
  "required": [
    "kind",
    "subject_type",
    "subject_id"
  ],
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/SupplyDocumentKind"
    },
    "subject_type": {
      "$ref": "#/components/schemas/SupplyDocumentSubjectType"
    },
    "subject_id": {
      "type": "string",
      "minLength": 1,
      "description": "Publisher uuid, tenant uuid, demand-partner uuid, or domain host."
    },
    "url": {
      "type": "string",
      "description": "Optional explicit crawl URL; omitted means derive from kind and subject."
    }
  }
}
SupplyDocumentCheck

schemas/SupplyDocumentKindschemas/SupplyDocumentSubjectTypeschemas/SupplyDocumentCheckStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "kind",
    "subject_type",
    "subject_id",
    "url",
    "status",
    "missing_count",
    "checked_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "kind": {
      "$ref": "#/components/schemas/SupplyDocumentKind"
    },
    "subject_type": {
      "$ref": "#/components/schemas/SupplyDocumentSubjectType"
    },
    "subject_id": {
      "type": "string"
    },
    "url": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/SupplyDocumentCheckStatus"
    },
    "content_hash": {
      "type": "string"
    },
    "owner_domain": {
      "type": "string"
    },
    "manager_domain": {
      "type": "string"
    },
    "missing_count": {
      "type": "integer",
      "minimum": 0
    },
    "error_summary": {
      "type": "string"
    },
    "checked_at": {
      "type": "string",
      "format": "date-time"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    },
    "details_json": {
      "type": "object",
      "additionalProperties": true
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
SupplyDocumentCheckList

schemas/SupplyDocumentCheck

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/SupplyDocumentCheck"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
SupplyDocumentFinding

{
  "type": "object",
  "description": "One structural finding from analyzing a crawled supply document.",
  "required": [
    "code",
    "severity",
    "message"
  ],
  "properties": {
    "code": {
      "type": "string",
      "description": "Stable machine-readable finding code (for example `duplicate_lines`, `conflicting_relationships`, `missing_owner_domain`, `duplicate_seller_ids`, `confidential_heavy`, `missing_seller_domains`).\n"
    },
    "severity": {
      "type": "string",
      "enum": [
        "info",
        "warning",
        "error"
      ]
    },
    "message": {
      "type": "string"
    },
    "count": {
      "type": "integer",
      "minimum": 0,
      "description": "How many document entries this finding covers (0 when not countable)."
    }
  }
}
SupplyDocumentAnalysis

schemas/SupplyDocumentKindschemas/SupplyDocumentFinding

{
  "type": "object",
  "description": "Deterministic structural analysis of one crawled ads.txt/app-ads.txt/sellers.json document. Counters irrelevant to the document kind are zero. risk_score is 0 (clean) to 100 (severely defective), derived only from the document's own structure.\n",
  "required": [
    "kind",
    "risk_score",
    "findings"
  ],
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/SupplyDocumentKind"
    },
    "risk_score": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "line_count": {
      "type": "integer",
      "minimum": 0
    },
    "direct_count": {
      "type": "integer",
      "minimum": 0
    },
    "reseller_count": {
      "type": "integer",
      "minimum": 0
    },
    "ad_system_count": {
      "type": "integer",
      "minimum": 0,
      "description": "Distinct advertising-system domains named by ads.txt data lines."
    },
    "duplicate_count": {
      "type": "integer",
      "minimum": 0
    },
    "conflict_count": {
      "type": "integer",
      "minimum": 0,
      "description": "Domain+account pairs listed as both DIRECT and RESELLER."
    },
    "malformed_count": {
      "type": "integer",
      "minimum": 0
    },
    "seller_count": {
      "type": "integer",
      "minimum": 0
    },
    "publisher_seller_count": {
      "type": "integer",
      "minimum": 0
    },
    "intermediary_seller_count": {
      "type": "integer",
      "minimum": 0
    },
    "both_seller_count": {
      "type": "integer",
      "minimum": 0
    },
    "confidential_count": {
      "type": "integer",
      "minimum": 0
    },
    "passthrough_count": {
      "type": "integer",
      "minimum": 0
    },
    "duplicate_seller_id_count": {
      "type": "integer",
      "minimum": 0
    },
    "missing_domain_count": {
      "type": "integer",
      "minimum": 0,
      "description": "Non-confidential sellers.json entries with no domain."
    },
    "has_owner_domain": {
      "type": "boolean"
    },
    "has_manager_domain": {
      "type": "boolean"
    },
    "has_contact": {
      "type": "boolean"
    },
    "findings": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/SupplyDocumentFinding"
      }
    }
  }
}
SupplyDocumentDiff

{
  "type": "object",
  "description": "Deterministic drift diff between one snapshot and the previous snapshot of the same document. All entry lists are rendered canonically and sorted. `unchanged` is true when the content hash matched the previous snapshot; a first snapshot has no previous_* fields and empty lists.\n",
  "required": [
    "unchanged"
  ],
  "properties": {
    "unchanged": {
      "type": "boolean"
    },
    "previous_snapshot_id": {
      "type": "string",
      "format": "uuid"
    },
    "previous_fetched_at": {
      "type": "string",
      "format": "date-time"
    },
    "added_lines": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "removed_lines": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "variable_changes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "added_sellers": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "removed_sellers": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "changed_sellers": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}
SupplyDocumentSnapshot

schemas/SupplyDocumentKindschemas/SupplyDocumentSubjectTypeschemas/SupplyDocumentDiffschemas/SupplyDocumentAnalysis

{
  "type": "object",
  "description": "One crawled supply document snapshot. List responses omit `body`; the single-snapshot read includes it.\n",
  "required": [
    "id",
    "tenant_id",
    "kind",
    "subject_type",
    "subject_id",
    "url",
    "content_hash",
    "fetched_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "kind": {
      "$ref": "#/components/schemas/SupplyDocumentKind"
    },
    "subject_type": {
      "$ref": "#/components/schemas/SupplyDocumentSubjectType"
    },
    "subject_id": {
      "type": "string"
    },
    "url": {
      "type": "string"
    },
    "content_hash": {
      "type": "string"
    },
    "fetched_at": {
      "type": "string",
      "format": "date-time"
    },
    "body": {
      "type": "string"
    },
    "diff": {
      "$ref": "#/components/schemas/SupplyDocumentDiff"
    },
    "analysis": {
      "$ref": "#/components/schemas/SupplyDocumentAnalysis"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
SupplyDocumentSnapshotList

schemas/SupplyDocumentSnapshot

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/SupplyDocumentSnapshot"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
SupplyHealthItem

schemas/SupplyDocumentKindschemas/SupplyDocumentSubjectTypeschemas/SupplyDocumentCheckStatusschemas/SupplyDocumentFinding

{
  "type": "object",
  "description": "Latest verification + drift + structural risk for one verified subject.",
  "required": [
    "kind",
    "subject_type",
    "subject_id",
    "status"
  ],
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/SupplyDocumentKind"
    },
    "subject_type": {
      "$ref": "#/components/schemas/SupplyDocumentSubjectType"
    },
    "subject_id": {
      "type": "string"
    },
    "subject_label": {
      "type": "string",
      "description": "Human-readable subject name (publisher/partner name) when resolvable."
    },
    "url": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/SupplyDocumentCheckStatus"
    },
    "checked_at": {
      "type": "string",
      "format": "date-time"
    },
    "stale": {
      "type": "boolean",
      "description": "True when the check has passed its expires_at freshness window."
    },
    "risk_score": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "drift_detected": {
      "type": "boolean",
      "description": "True when the latest snapshot's diff against its predecessor is non-empty."
    },
    "missing_count": {
      "type": "integer",
      "minimum": 0
    },
    "error_summary": {
      "type": "string"
    },
    "top_findings": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/SupplyDocumentFinding"
      }
    }
  }
}
SupplyTransparencyHealthReport

schemas/SupplyHealthItem

{
  "type": "object",
  "description": "Aggregate supply-chain transparency posture for a tenant - verification coverage over publishers and demand partners, per-subject latest status/risk/drift, and the totals a console dashboard or agent needs to prioritize fixes.\n",
  "required": [
    "tenant_id",
    "generated_at",
    "items",
    "checks_total",
    "checks_ok",
    "checks_failing",
    "checks_stale"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "generated_at": {
      "type": "string",
      "format": "date-time"
    },
    "checks_total": {
      "type": "integer",
      "minimum": 0
    },
    "checks_ok": {
      "type": "integer",
      "minimum": 0
    },
    "checks_failing": {
      "type": "integer",
      "minimum": 0
    },
    "checks_stale": {
      "type": "integer",
      "minimum": 0
    },
    "drift_count": {
      "type": "integer",
      "minimum": 0,
      "description": "Subjects whose most recent snapshot shows drift from its predecessor."
    },
    "publishers_total": {
      "type": "integer",
      "minimum": 0
    },
    "publishers_verified": {
      "type": "integer",
      "minimum": 0,
      "description": "Publishers with at least one non-stale ads.txt/app-ads.txt check."
    },
    "demand_partners_total": {
      "type": "integer",
      "minimum": 0
    },
    "demand_partners_verified": {
      "type": "integer",
      "minimum": 0,
      "description": "Demand partners with at least one non-stale sellers.json check."
    },
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/SupplyHealthItem"
      }
    }
  }
}
TenantUpdate

schemas/Brandingschemas/Entitlementschemas/GovernorLimitschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "description": "Body for PUT /v1/operator/tenants/{tenant_id}. Each top-level field independently replaces its respective state when present; an omitted field leaves that state unchanged. `branding` replaces all four white-label columns together (omitted sub-fields clear to null); `entitlements`, when present, replaces the tenant's *entire* entitlement set (not a merge).\n",
  "properties": {
    "branding": {
      "$ref": "#/components/schemas/Branding"
    },
    "entitlements": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Entitlement"
      }
    },
    "settlement_currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "governor": {
      "$ref": "#/components/schemas/GovernorLimit"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "supply_contact_email": {
      "type": "string",
      "description": "sellers.json `contact_email`; an empty string clears it."
    },
    "creative_auto_approve": {
      "type": "boolean",
      "description": "Creative review policy; see Tenant.creative_auto_approve."
    },
    "sanctioned_countries": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 2,
        "maxLength": 2
      },
      "description": "Replaces the sanctioned-country list (ISO-3166 alpha-2); [] clears it. See Tenant.sanctioned_countries."
    },
    "request_quota_per_day": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Requests per UTC day; 0 = unlimited. See Tenant.request_quota_per_day."
    },
    "serving_suspended": {
      "type": "boolean",
      "description": "Serving kill switch. See Tenant.serving_suspended."
    },
    "timezone": {
      "type": "string",
      "description": "IANA time zone (validated); an empty string resets to UTC. See Tenant.timezone."
    },
    "bad_input_http_errors": {
      "type": "boolean",
      "description": "Bad player input posture (SR-1217): false (default) answers malformed tag / OpenRTB input the way a player degrades gracefully (an empty VAST document on /vast, a body-less 204 on /ortb); true opts into typed 4xx errors for integration debugging.\n"
    },
    "tag_id": {
      "type": "string",
      "maxLength": 16,
      "description": "Certification-authority id (16 hex characters); an empty string clears it. See Tenant.tag_id (SR-1212)."
    },
    "contact_address": {
      "type": "string",
      "maxLength": 512,
      "description": "sellers.json `contact_address`; an empty string clears it. See Tenant.contact_address (SR-1212)."
    },
    "stale_plan_fail_open": {
      "type": "boolean",
      "description": "Stale-plan fail-open posture. See Tenant.stale_plan_fail_open (SR-1235)."
    }
  }
}
TenantAudioToVideoUpdate

schemas/AudioToVideoConfig

{
  "type": "object",
  "description": "Body for PUT /v1/tenants/{tenant_id}/audio-to-video. Each field independently replaces its respective column when present; an omitted field leaves that level unchanged (same partial- update convention as PlacementUpdate.stitch).\n",
  "properties": {
    "audio_to_video": {
      "$ref": "#/components/schemas/AudioToVideoConfig"
    },
    "audio_to_video_by_brand": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/AudioToVideoConfig"
      }
    }
  }
}
TenantRatePlanAssign

{
  "type": "object",
  "required": [
    "plan_id"
  ],
  "properties": {
    "plan_id": {
      "type": "string",
      "format": "uuid",
      "description": "rate_plan.id to assign."
    },
    "apply_entitlement_pack": {
      "type": "boolean",
      "description": "Replace the tenant's entitlements with the plan's pack (default true)."
    }
  }
}
Cell

{
  "type": "object",
  "required": [
    "id",
    "region",
    "tier",
    "status",
    "serve_replicas",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "region": {
      "type": "string"
    },
    "tier": {
      "type": "string",
      "enum": [
        "shared",
        "dedicated"
      ],
      "x-enum-varnames": [
        "CellTierShared",
        "CellTierDedicated"
      ]
    },
    "status": {
      "type": "string",
      "enum": [
        "ACTIVE",
        "CORDONED",
        "DRAINING"
      ],
      "x-enum-varnames": [
        "CellStatusACTIVE",
        "CellStatusCORDONED",
        "CellStatusDRAINING"
      ]
    },
    "serve_replicas": {
      "type": "integer"
    },
    "endpoints": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Service endpoints keyed by role (`serve`, `pland`)."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
CellList

schemas/Cell

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Cell"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
TenantCreate

schemas/GovernorLimitschemas/SupplyTransparencyPolicy

{
  "example": {
    "name": "Acme Media",
    "slug": "acme",
    "region": "us",
    "cell_id": "cell-us-east-1",
    "settlement_currency": "USD",
    "creative_auto_approve": true
  },
  "type": "object",
  "required": [
    "name",
    "slug",
    "region",
    "cell_id"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "slug": {
      "type": "string",
      "minLength": 1
    },
    "region": {
      "type": "string",
      "minLength": 1
    },
    "timezone": {
      "type": "string",
      "description": "IANA time zone; defaults to UTC. See Tenant.timezone."
    },
    "cell_id": {
      "type": "string",
      "minLength": 1
    },
    "default_delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400
    },
    "sandbox": {
      "type": "boolean",
      "default": false,
      "description": "Create a sandbox tenant (SR-1240 developer platform); see Tenant.sandbox. Immutable after creation."
    },
    "settlement_currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "governor": {
      "$ref": "#/components/schemas/GovernorLimit"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "creative_auto_approve": {
      "type": "boolean",
      "default": true,
      "description": "Creative review policy; see Tenant.creative_auto_approve."
    },
    "sanctioned_countries": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 2,
        "maxLength": 2
      },
      "description": "ISO-3166 alpha-2 countries answered no-bid (sanctioned_geo). See Tenant.sanctioned_countries."
    },
    "request_quota_per_day": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Requests per UTC day; 0 = unlimited."
    },
    "serving_suspended": {
      "type": "boolean",
      "description": "Serving kill switch (default false)."
    },
    "bad_input_http_errors": {
      "type": "boolean",
      "description": "Bad player input posture (SR-1217): false (default) answers malformed tag / OpenRTB input the way a player degrades gracefully (an empty VAST document on /vast, a body-less 204 on /ortb); true opts into typed 4xx errors for integration debugging.\n"
    }
  }
}
TenantList

schemas/Tenant

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Tenant"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
OnboardTenantRequest

schemas/Entitlement

{
  "type": "object",
  "required": [
    "name",
    "slug",
    "region",
    "admin_email"
  ],
  "description": "Request body for POST /v1/operator/onboarding/tenants. Idempotency is carried by the Idempotency-Key header; optional cell_id pins the target cell, otherwise the onboarding pipeline chooses a healthy cell in the requested region.\n",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "slug": {
      "type": "string",
      "minLength": 1
    },
    "region": {
      "type": "string",
      "minLength": 1
    },
    "cell_id": {
      "type": "string"
    },
    "entitlements": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Entitlement"
      }
    },
    "default_delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400
    },
    "admin_email": {
      "type": "string",
      "format": "email",
      "minLength": 1
    },
    "admin_name": {
      "type": "string"
    },
    "hostname": {
      "type": "string",
      "description": "Optional custom serving domain to provision."
    },
    "cname_target": {
      "type": "string",
      "description": "Expected CNAME target for hostname verification."
    }
  }
}
OnboardDomain

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "hostname",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "hostname": {
      "type": "string"
    },
    "cname_target": {
      "type": "string"
    },
    "status": {
      "type": "string"
    },
    "cert_ref": {
      "type": "string"
    },
    "failure_reason": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
TenantOnboardingResponse

schemas/Tenantschemas/SealingKeyschemas/Userschemas/OnboardDomain

{
  "type": "object",
  "required": [
    "tenant",
    "sealing_key",
    "admin_user"
  ],
  "properties": {
    "tenant": {
      "$ref": "#/components/schemas/Tenant"
    },
    "sealing_key": {
      "$ref": "#/components/schemas/SealingKey"
    },
    "admin_user": {
      "$ref": "#/components/schemas/User"
    },
    "domain": {
      "$ref": "#/components/schemas/OnboardDomain"
    }
  }
}
Publisher

schemas/LifecycleStatusschemas/AdminPricingschemas/PublisherSellerschemas/AudioToVideoConfig

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "public_id",
    "name",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "public_id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "pricing": {
      "$ref": "#/components/schemas/AdminPricing"
    },
    "whitelist_apps": {
      "type": "boolean",
      "description": "When true, serve no-bids unless the request resolves to a non-blocked AppLookup (`inventory_not_allowlisted` / `app_blocked`; docs/design/22-ip-list-and-identity-envelope.md).\n"
    },
    "whitelist_domains": {
      "type": "boolean",
      "description": "When true, serve no-bids unless the request site/app domain matches publisher.domain (`inventory_not_allowlisted`; docs/design/22-ip-list-and-identity-envelope.md).\n"
    },
    "serving_fee": {
      "type": "string",
      "description": "Flat serving fee (decimal CPM) subtracted on the publisher side of every demand win (docs/design/08-economics.md)."
    },
    "audio_partner_cost": {
      "type": "string",
      "description": "Audio-partner cost (decimal CPM, 4 dp): added to the floor sent to AUDIO demand routes and deducted from AUDIO bids (docs/design/08-economics.md \"Outbound floor gross-up\"). Empty string clears it (no cost); new publishers seed the platform default 0.3500.\n"
    },
    "domain": {
      "type": "string",
      "description": "Publisher ads.txt / sellers.json domain."
    },
    "inventory_partner_domains": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Inventory partner root domains for ads.txt INVENTORYPARTNERDOMAIN= (IAB inventory sharing)."
    },
    "sellers": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PublisherSeller"
      }
    },
    "delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400,
      "description": "Supply-side delivery window override (seconds); see delivery-timing.md."
    },
    "audio_to_video": {
      "$ref": "#/components/schemas/AudioToVideoConfig"
    },
    "allowed_advertisers": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 253
      },
      "description": "Advertiser allow-list (SR-1217): when non-empty, only a bid whose adomain matches an entry (exact or parent domain) may serve on this publisher's placements; every other bid loses with `advertiser_not_allowed`. A placement's own allowed_advertisers takes precedence when set. Empty / [] = no allow-list.\n"
    },
    "blocked_media_url_substrings": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512
      },
      "description": "Media-URL substring blocklist (SR-1217): a bid whose creative media URL contains any entry (case-insensitive) loses with `blocked_media_url`. Empty / [] = off.\n"
    },
    "demand_tmax_cap_ms": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10000,
      "description": "Demand latency cap (ms, SR-1217): the demand fan-out budget of every route dialed for a request under this publisher is capped at this value regardless of the request's tmax. 0 / omitted = no cap beyond tmax.\n"
    },
    "vast_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /vast answers an empty VAST document (reason `vast_paused`) for this publisher."
    },
    "ortb_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /ortb answers no-bid (reason `ortb_paused`) for this publisher."
    },
    "mask_vast_trackers": {
      "type": "boolean",
      "description": "Mask buyer trackers (SR-1217): a buyer VAST's own Impression / Tracking / Error URLs are removed from the document the player receives, cached server-side and fired by the platform when the player hits the masked tracker.\n"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
PublisherCreate

schemas/AdminPricingschemas/PublisherSellerschemas/AudioToVideoConfig

{
  "example": {
    "public_id": "acme-pub",
    "name": "Acme Publisher",
    "domain": "publisher.acme.example",
    "pricing": {
      "type": "REVSHARE",
      "value": "0.20"
    }
  },
  "type": "object",
  "required": [
    "public_id",
    "name"
  ],
  "properties": {
    "public_id": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "pricing": {
      "$ref": "#/components/schemas/AdminPricing"
    },
    "whitelist_apps": {
      "type": "boolean"
    },
    "whitelist_domains": {
      "type": "boolean"
    },
    "serving_fee": {
      "type": "string",
      "description": "Flat serving fee (decimal CPM) subtracted on the publisher side of every demand win (docs/design/08-economics.md)."
    },
    "audio_partner_cost": {
      "type": "string",
      "description": "Audio-partner cost (decimal CPM, 4 dp): added to the floor sent to AUDIO demand routes and deducted from AUDIO bids (docs/design/08-economics.md \"Outbound floor gross-up\"). Empty string clears it (no cost); new publishers seed the platform default 0.3500.\n"
    },
    "domain": {
      "type": "string"
    },
    "inventory_partner_domains": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Inventory partner root domains for ads.txt INVENTORYPARTNERDOMAIN= (IAB inventory sharing)."
    },
    "sellers": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PublisherSeller"
      }
    },
    "delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400
    },
    "audio_to_video": {
      "$ref": "#/components/schemas/AudioToVideoConfig"
    },
    "allowed_advertisers": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 253
      },
      "description": "Advertiser allow-list (SR-1217): when non-empty, only a bid whose adomain matches an entry (exact or parent domain) may serve on this publisher's placements; every other bid loses with `advertiser_not_allowed`. A placement's own allowed_advertisers takes precedence when set. Empty / [] = no allow-list.\n"
    },
    "blocked_media_url_substrings": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512
      },
      "description": "Media-URL substring blocklist (SR-1217): a bid whose creative media URL contains any entry (case-insensitive) loses with `blocked_media_url`. Empty / [] = off.\n"
    },
    "demand_tmax_cap_ms": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10000,
      "description": "Demand latency cap (ms, SR-1217): the demand fan-out budget of every route dialed for a request under this publisher is capped at this value regardless of the request's tmax. 0 / omitted = no cap beyond tmax.\n"
    },
    "vast_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /vast answers an empty VAST document (reason `vast_paused`) for this publisher."
    },
    "ortb_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /ortb answers no-bid (reason `ortb_paused`) for this publisher."
    },
    "mask_vast_trackers": {
      "type": "boolean",
      "description": "Mask buyer trackers (SR-1217): a buyer VAST's own Impression / Tracking / Error URLs are removed from the document the player receives, cached server-side and fired by the platform when the player hits the masked tracker.\n"
    }
  }
}
PublisherUpdate

schemas/AdminPricingschemas/PublisherSellerschemas/AudioToVideoConfig

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "pricing": {
      "$ref": "#/components/schemas/AdminPricing"
    },
    "whitelist_apps": {
      "type": "boolean"
    },
    "whitelist_domains": {
      "type": "boolean"
    },
    "serving_fee": {
      "type": "string",
      "description": "Flat serving fee (decimal CPM) subtracted on the publisher side of every demand win (docs/design/08-economics.md)."
    },
    "audio_partner_cost": {
      "type": "string",
      "description": "Audio-partner cost (decimal CPM, 4 dp): added to the floor sent to AUDIO demand routes and deducted from AUDIO bids (docs/design/08-economics.md \"Outbound floor gross-up\"). Empty string clears it (no cost); new publishers seed the platform default 0.3500.\n"
    },
    "domain": {
      "type": "string"
    },
    "inventory_partner_domains": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Inventory partner root domains for ads.txt INVENTORYPARTNERDOMAIN= (IAB inventory sharing)."
    },
    "sellers": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PublisherSeller"
      }
    },
    "delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400
    },
    "audio_to_video": {
      "$ref": "#/components/schemas/AudioToVideoConfig"
    },
    "allowed_advertisers": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 253
      },
      "description": "Advertiser allow-list (SR-1217): when non-empty, only a bid whose adomain matches an entry (exact or parent domain) may serve on this publisher's placements; every other bid loses with `advertiser_not_allowed`. A placement's own allowed_advertisers takes precedence when set. Empty / [] = no allow-list.\n"
    },
    "blocked_media_url_substrings": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512
      },
      "description": "Media-URL substring blocklist (SR-1217): a bid whose creative media URL contains any entry (case-insensitive) loses with `blocked_media_url`. Empty / [] = off.\n"
    },
    "demand_tmax_cap_ms": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10000,
      "description": "Demand latency cap (ms, SR-1217): the demand fan-out budget of every route dialed for a request under this publisher is capped at this value regardless of the request's tmax. 0 / omitted = no cap beyond tmax.\n"
    },
    "vast_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /vast answers an empty VAST document (reason `vast_paused`) for this publisher."
    },
    "ortb_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /ortb answers no-bid (reason `ortb_paused`) for this publisher."
    },
    "mask_vast_trackers": {
      "type": "boolean",
      "description": "Mask buyer trackers (SR-1217): a buyer VAST's own Impression / Tracking / Error URLs are removed from the document the player receives, cached server-side and fired by the platform when the player hits the masked tracker.\n"
    }
  }
}
PublisherList

schemas/Publisher

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Publisher"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
StitchConfig

{
  "type": "object",
  "description": "Real-time stitch configuration for a placement (docs/design/11-stitching.md). Enabling stitch requires the tenant `stitch` entitlement.\n",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "max_ads": {
      "type": "integer",
      "minimum": 2
    },
    "max_video": {
      "type": "integer",
      "minimum": 0
    },
    "max_audio": {
      "type": "integer",
      "minimum": 0
    },
    "floor": {
      "type": "string",
      "description": "Decimal CPM floor for the combined stitch bid."
    },
    "fee": {
      "type": "string",
      "description": "Flat stitch fee (decimal CPM) subtracted once from the combined bid."
    },
    "accept_floor_pct": {
      "type": "string",
      "description": "Accept-% of floor under real-time stitch (fraction 0-1 as a decimal string, e.g. \"0.80\"): partners may bid this fraction of the floor because the stitched slate clears the floor as a whole (docs/design/08-economics.md \"Floor precedence\"). Empty = 1.\n"
    },
    "ignore_duration": {
      "type": "boolean"
    },
    "dedupe": {
      "type": "boolean"
    },
    "dedupe_media": {
      "type": "boolean"
    },
    "dedupe_advertiser": {
      "type": "boolean"
    },
    "dedupe_category": {
      "type": "boolean"
    },
    "max_duration_sec": {
      "type": "integer",
      "minimum": 0
    },
    "cpm_cap": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "min": {
          "type": "string"
        },
        "max": {
          "type": "string"
        },
        "increment": {
          "type": "string"
        }
      }
    }
  }
}
AdminPricing

{
  "type": "object",
  "description": "Economics pricing (REVSHARE|CPM) as decimal string value (4dp).",
  "properties": {
    "type": {
      "type": "string",
      "enum": [
        "REVSHARE",
        "CPM"
      ]
    },
    "value": {
      "type": "string"
    }
  }
}
AdminCpmCap

{
  "type": "object",
  "description": "CPM cap band applied on the response-to-supply net price path.",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "min": {
      "type": "string"
    },
    "max": {
      "type": "string"
    },
    "increment": {
      "type": "string"
    }
  }
}
WarmPoolConfig

{
  "type": "object",
  "description": "Warm-pool (bid cache) media flags for a placement; requires warm_pool entitlement.",
  "properties": {
    "audio": {
      "type": "boolean"
    },
    "video": {
      "type": "boolean"
    },
    "only_cache": {
      "type": "boolean",
      "description": "When true, live demand is async-warmed; sync path uses cache."
    },
    "ttl_class": {
      "type": "string",
      "enum": [
        "",
        "default",
        "short",
        "long",
        "buyer_exp"
      ],
      "description": "Placement-level cache lifetime class for warmed bids (docs/design/17-warm-pool.md \"TTL classes\"): ''/default = 40 min, short = 10 min, long = 60 min, buyer_exp = the buyer's own bid.exp (capped at 60 min). A partner's warm_pool_ttl_class overrides it.\n"
    }
  }
}
DemandAttachmentConfig

{
  "type": "object",
  "description": "Entitlement-gated demand attachment for a placement (docs/design/26-demand-attachment.md). Enabling attachment requires the tenant `demand_attachment` entitlement.\n",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "max_attachments": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "allow_duplicate_seat_pct": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "max_pmp_in_bundle": {
      "type": "integer",
      "minimum": 0
    },
    "partner_allow_list": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "attach_budget_ms": {
      "type": "integer",
      "minimum": 0
    }
  }
}
DualModeConfig

{
  "type": "object",
  "description": "Dual-mode auction: one demand fanout at long_timeout_ms; bids arriving after short_timeout_ms are discarded for this request (not a second pass).\n",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "short_timeout_ms": {
      "type": "integer",
      "minimum": 1
    },
    "long_timeout_ms": {
      "type": "integer",
      "minimum": 1
    }
  }
}
EntityVerification

{
  "type": "object",
  "description": "Per-entity verification binding (vendor slot A–D, PIXEL|WRAPPER).",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "vendor": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C",
        "D"
      ]
    },
    "mode": {
      "type": "string",
      "enum": [
        "PIXEL",
        "WRAPPER"
      ]
    },
    "vendor_key": {
      "type": "string"
    }
  }
}
FrequencyCap

{
  "type": "object",
  "description": "Sliding-window frequency cap (HOUR|DAY|WEEK|MONTH|LIFETIME); multiple caps AND'd. Across scopes the most restrictive wins (creative association → line item → order).\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "duration": {
      "type": "integer",
      "minimum": 1
    },
    "limit": {
      "type": "integer",
      "minimum": 1
    },
    "unit": {
      "type": "string",
      "enum": [
        "HOUR",
        "DAY",
        "WEEK",
        "MONTH",
        "LIFETIME"
      ]
    }
  }
}
FrequencyCapInput

{
  "type": "object",
  "required": [
    "duration",
    "limit",
    "unit"
  ],
  "properties": {
    "duration": {
      "type": "integer",
      "minimum": 1
    },
    "limit": {
      "type": "integer",
      "minimum": 1
    },
    "unit": {
      "type": "string",
      "enum": [
        "HOUR",
        "DAY",
        "WEEK",
        "MONTH",
        "LIFETIME"
      ]
    }
  }
}
Daypart

{
  "type": "object",
  "description": "One day-of-week window (docs/decisions/D33-line-item-dayparting.md). day_of_week is 0=Sunday..6=Saturday. Both hours unset = whole day; else [start_hour, end_hour).\n",
  "required": [
    "day_of_week"
  ],
  "properties": {
    "day_of_week": {
      "type": "integer",
      "minimum": 0,
      "maximum": 6
    },
    "start_hour": {
      "type": "integer",
      "minimum": 0,
      "maximum": 23
    },
    "end_hour": {
      "type": "integer",
      "minimum": 1,
      "maximum": 24
    }
  }
}
LineItemFlight

{
  "type": "object",
  "description": "One sequential budget segment under a line item (GC-05, design 32 §10). Sibling flights never overlap and subdivide the line item's flight window + lifetime/daily envelope — they never widen it. id is the flight's stable identity; delivery counters key on it.\n",
  "required": [
    "start_at",
    "end_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Server-minted flight identity. Omit on create; carry it on update to edit the flight in place, preserving its delivered counters.\n"
    },
    "sequence": {
      "type": "integer",
      "readOnly": true,
      "description": "1-based position derived from start_at order; server-computed and returned."
    },
    "start_at": {
      "type": "string",
      "format": "date-time"
    },
    "end_at": {
      "type": "string",
      "format": "date-time",
      "description": "Exclusive end; must be after start_at."
    },
    "goal": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Count of the line item's goal_type metric for this segment; omit for uncapped. Only accepted when goal_type is IMPRESSIONS, COMPLETIONS, CLICKS, or SPEND. For SPEND (and REVENUE) the money goal IS the flight budget: the budget stop covers it and a goal set here is never enforced or carried — cap money delivery per flight with budget instead.\n"
    },
    "budget": {
      "type": "string",
      "description": "Decimal money string (4dp), e.g. \"5000.0000\"; omit for uncapped spend."
    },
    "carryover_policy": {
      "type": "string",
      "enum": [
        "NONE",
        "CARRY_FORWARD"
      ],
      "x-enum-varnames": [
        "FlightCarryoverNONE",
        "FlightCarryoverCARRYFORWARD"
      ],
      "description": "Whether this flight receives the previous flight's unmet envelope: CARRY_FORWARD adds max(0, prior effective goal/budget - prior delivered) to this flight's own goal/budget (only when both flights define the value). Default NONE.\n"
    }
  }
}
FanoutConfig

{
  "type": "object",
  "description": "Floor-exploration route multiplication (docs/design/06-demand.md).",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "count": {
      "type": "integer",
      "minimum": 1
    },
    "use_default_floor": {
      "type": "boolean"
    },
    "min_floor": {
      "type": "string"
    },
    "max_floor": {
      "type": "string"
    },
    "increment": {
      "type": "string"
    }
  }
}
PublisherSeller

schemas/SellerIdentifier

{
  "type": "object",
  "required": [
    "seller_id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "seller_id": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string"
    },
    "domain": {
      "type": "string"
    },
    "seller_type": {
      "type": "string",
      "enum": [
        "PUBLISHER",
        "INTERMEDIARY",
        "BOTH"
      ]
    },
    "is_confidential": {
      "type": "boolean"
    },
    "is_passthrough": {
      "type": "boolean",
      "description": "sellers.json 1.0 `is_passthrough` - the seller passes the request through without taking ownership of the inventory.\n"
    },
    "identifiers": {
      "type": "array",
      "maxItems": 50,
      "items": {
        "$ref": "#/components/schemas/SellerIdentifier"
      },
      "description": "sellers.json 1.0 per-seller `identifiers` (TAG-ID, DUNS, and similar)."
    }
  }
}
SellerIdentifier

{
  "type": "object",
  "required": [
    "name",
    "value"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "value": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256
    }
  }
}
WeightedCreativeRef

{
  "type": "object",
  "required": [
    "creative_id",
    "weight"
  ],
  "description": "One line-item↔creative association: rotation weight plus association-level state, optional flight window, and click override (design 30 §2E).\n",
  "properties": {
    "creative_id": {
      "type": "string",
      "format": "uuid"
    },
    "weight": {
      "type": "integer",
      "minimum": 1
    },
    "active": {
      "type": "boolean",
      "default": true,
      "description": "Inactive associations never rotate; the creative itself is untouched."
    },
    "start_at": {
      "type": "string",
      "format": "date-time",
      "description": "Association flight start; omit for no start bound."
    },
    "end_at": {
      "type": "string",
      "format": "date-time",
      "description": "Association flight end; omit for no end bound."
    },
    "click_url": {
      "type": "string",
      "description": "Click-through override for this association; empty inherits the creative's click_url."
    }
  }
}
AudienceStringRule

{
  "type": "object",
  "required": [
    "value"
  ],
  "properties": {
    "value": {
      "type": "string"
    },
    "excluded": {
      "type": "boolean"
    }
  }
}
AudienceIntRule

{
  "type": "object",
  "required": [
    "value"
  ],
  "properties": {
    "value": {
      "type": "integer"
    },
    "excluded": {
      "type": "boolean"
    }
  }
}
AudienceGeoRule

{
  "type": "object",
  "required": [
    "type"
  ],
  "description": "Geo targeting row (proto GeoRule).",
  "properties": {
    "type": {
      "type": "string",
      "description": "Granularity: continent, country, region, or city."
    },
    "excluded": {
      "type": "boolean"
    },
    "continent": {
      "type": "string"
    },
    "country": {
      "type": "string"
    },
    "region": {
      "type": "string"
    },
    "city": {
      "type": "integer",
      "format": "int32"
    }
  }
}
AudienceMetroRule

{
  "type": "object",
  "required": [
    "country",
    "metro"
  ],
  "description": "DMA/metro targeting row (proto MetroRule).",
  "properties": {
    "country": {
      "type": "string"
    },
    "metro": {
      "type": "integer",
      "format": "int32"
    },
    "excluded": {
      "type": "boolean"
    }
  }
}
AudiencePlacementRule

{
  "type": "object",
  "required": [
    "placement_id"
  ],
  "description": "Placement allow/block row (proto PlacementRule).",
  "properties": {
    "placement_id": {
      "type": "string",
      "format": "uuid"
    },
    "excluded": {
      "type": "boolean"
    }
  }
}
AudienceContentRules

{
  "type": "object",
  "description": "Content metadata targeting (proto ContentRules).",
  "properties": {
    "languages": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "languages_excluded": {
      "type": "boolean"
    },
    "channels": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "channels_excluded": {
      "type": "boolean"
    },
    "genres": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "genres_excluded": {
      "type": "boolean"
    },
    "ratings": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "ratings_excluded": {
      "type": "boolean"
    },
    "titles": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "titles_excluded": {
      "type": "boolean"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "categories_excluded": {
      "type": "boolean"
    },
    "keywords": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "keywords_excluded": {
      "type": "boolean"
    }
  }
}
ProximityTarget

{
  "type": "object",
  "properties": {
    "lat": {
      "type": "number"
    },
    "lon": {
      "type": "number"
    },
    "radius_km": {
      "type": "number",
      "minimum": 0
    }
  }
}
AppPricingEntry

schemas/AdminPricingschemas/AdminCpmCap

{
  "type": "object",
  "properties": {
    "floor": {
      "type": "string"
    },
    "pricing": {
      "$ref": "#/components/schemas/AdminPricing"
    },
    "upstream_cpm_cap": {
      "$ref": "#/components/schemas/AdminCpmCap"
    }
  }
}
RouteApprovalEntry

{
  "type": "object",
  "properties": {
    "status": {
      "type": "string"
    },
    "macros": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    }
  }
}
AppLookup

{
  "type": "object",
  "description": "App-resolution cache row (docs/design/02-data-model.md). Keyed by cache_key (publisher_public_id|bundle_id via plan.AppLookupKey).\n",
  "required": [
    "tenant_id",
    "cache_key",
    "publisher_public_id",
    "blocked"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "cache_key": {
      "type": "string"
    },
    "publisher_public_id": {
      "type": "string"
    },
    "bundle_id": {
      "type": "string"
    },
    "platform_id": {
      "type": "string",
      "format": "uuid"
    },
    "store_url": {
      "type": "string"
    },
    "app_id": {
      "type": "string",
      "format": "uuid"
    },
    "blocked": {
      "type": "boolean"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
AppLookupCreate

{
  "type": "object",
  "required": [
    "publisher_public_id"
  ],
  "properties": {
    "publisher_public_id": {
      "type": "string",
      "minLength": 1
    },
    "bundle_id": {
      "type": "string"
    },
    "platform_id": {
      "type": "string",
      "format": "uuid"
    },
    "store_url": {
      "type": "string"
    },
    "app_id": {
      "type": "string",
      "format": "uuid"
    },
    "blocked": {
      "type": "boolean"
    }
  }
}
AppLookupUpdate

{
  "type": "object",
  "properties": {
    "platform_id": {
      "type": "string",
      "format": "uuid"
    },
    "store_url": {
      "type": "string"
    },
    "app_id": {
      "type": "string",
      "format": "uuid"
    },
    "blocked": {
      "type": "boolean"
    }
  }
}
AppLookupList

schemas/AppLookup

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AppLookup"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
VerificationVendorConfig

{
  "type": "object",
  "description": "Tenant-configured templates for one verification vendor slot (A–D). Distinct from per-entity EntityVerification references (RIP-133 WS10).\n",
  "required": [
    "id",
    "tenant_id",
    "vendor"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "vendor": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C",
        "D"
      ]
    },
    "pixel_url": {
      "type": "string"
    },
    "wrapper_url": {
      "type": "string"
    },
    "js_resource_url": {
      "type": "string"
    },
    "api_framework": {
      "type": "string"
    },
    "prebid_url": {
      "type": "string"
    },
    "prebid_timeout_ms": {
      "type": "integer",
      "minimum": 0
    },
    "sampling_pct": {
      "type": "string",
      "description": "Decimal 0-100; omit/empty = always measure."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
VerificationVendorConfigCreate

{
  "type": "object",
  "required": [
    "vendor"
  ],
  "properties": {
    "vendor": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C",
        "D"
      ]
    },
    "pixel_url": {
      "type": "string"
    },
    "wrapper_url": {
      "type": "string"
    },
    "js_resource_url": {
      "type": "string"
    },
    "api_framework": {
      "type": "string"
    },
    "prebid_url": {
      "type": "string"
    },
    "prebid_timeout_ms": {
      "type": "integer",
      "minimum": 0
    },
    "sampling_pct": {
      "type": "string"
    }
  }
}
VerificationVendorConfigUpdate

{
  "type": "object",
  "properties": {
    "pixel_url": {
      "type": "string"
    },
    "wrapper_url": {
      "type": "string"
    },
    "js_resource_url": {
      "type": "string"
    },
    "api_framework": {
      "type": "string"
    },
    "prebid_url": {
      "type": "string"
    },
    "prebid_timeout_ms": {
      "type": "integer",
      "minimum": 0
    },
    "sampling_pct": {
      "type": "string"
    }
  }
}
VerificationVendorConfigList

schemas/VerificationVendorConfig

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/VerificationVendorConfig"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
AttributionConfig

schemas/ProductAttributionMatchType

{
  "type": "object",
  "description": "Per-tenant conversion attribution settings (migrations/postgres/0059). Deterministic last-touch in v1: a conversion attributes to the most recent click within click_window_seconds, else (when view_through_enabled) the most recent impression within view_window_seconds. One config per tenant; no per-line-item overrides in v1.\n",
  "required": [
    "tenant_id",
    "click_window_seconds",
    "view_window_seconds",
    "view_through_enabled",
    "enabled"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Absent when the tenant is still on platform defaults (no row written)."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "click_window_seconds": {
      "type": "integer",
      "minimum": 1,
      "maximum": 3888000,
      "description": "Click-through lookback window in seconds (default 604800 = 7 days; max 3888000 = 45 days, the click_ref token acceptance horizon).\n"
    },
    "view_window_seconds": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2592000,
      "description": "View-through lookback window in seconds (default 86400 = 1 day; max 30 days)."
    },
    "view_through_enabled": {
      "type": "boolean",
      "description": "Whether impressions are eligible touchpoints (view-through) at all."
    },
    "enabled": {
      "type": "boolean",
      "description": "Master switch — when false, conversions are ingested but not attributed."
    },
    "product_attribution_match_type": {
      "$ref": "#/components/schemas/ProductAttributionMatchType"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ConversionTag

{
  "type": "object",
  "description": "Advertiser conversion ingest snippets (pixel + S2S). Placeholders use curly braces; replace {click_ref} with the sealed rt_clkref value from the landing URL and {label} with a conversion_label matching [a-z0-9_-]{1,64}.\n",
  "required": [
    "pixel_url_template",
    "pixel_html",
    "s2s_url",
    "s2s_body_example"
  ],
  "properties": {
    "pixel_url_template": {
      "type": "string",
      "description": "GET pixel URL template including clkref and label query params."
    },
    "pixel_html": {
      "type": "string",
      "description": "1x1 image tag ready to paste on a thank-you / conversion page."
    },
    "s2s_url": {
      "type": "string",
      "description": "POST /conversion endpoint for server-to-server fires."
    },
    "s2s_body_example": {
      "type": "string",
      "description": "Example JSON body for S2S ingest."
    },
    "notes": {
      "type": "string",
      "description": "Operator-facing setup notes (no secrets)."
    }
  }
}
UserProfile

schemas/UserProfileAttribute

{
  "type": "object",
  "description": "Cell-local user profile snapshot (design 33 / CP-4). Opaque user_key; attributes are typed scalars (string|int|bool|decimal). Used for targeting expressions and RTBF.\n",
  "required": [
    "tenant_id",
    "user_key",
    "found"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "user_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256
    },
    "found": {
      "type": "boolean",
      "description": "false on miss / after RTBF"
    },
    "opt_out": {
      "type": "boolean",
      "description": "When true, targeting treats the profile as empty"
    },
    "attributes": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/UserProfileAttribute"
      },
      "description": "At most 64 keys; key ≤64 chars; string/decimal values ≤256 chars."
    },
    "tags": {
      "type": "array",
      "maxItems": 32,
      "items": {
        "type": "string",
        "maxLength": 256
      }
    },
    "segments": {
      "type": "array",
      "maxItems": 128,
      "items": {
        "type": "string",
        "maxLength": 256
      },
      "description": "Audience segment ids carried on the profile."
    },
    "audit_id": {
      "type": "string",
      "description": "AuditEnvelope id for the mutation that produced this snapshot (writes only)."
    }
  }
}
UserProfileAttribute

{
  "type": "object",
  "required": [
    "kind",
    "value"
  ],
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "string",
        "int",
        "bool",
        "decimal"
      ]
    },
    "value": {
      "type": "string",
      "description": "Canonical string form — int digits, bool \"true\"|\"false\", decimal money-safe string, or free-form string. Parsed according to kind.\n"
    }
  }
}
UserProfileUpsert

schemas/UserProfileAttribute

{
  "type": "object",
  "description": "Replace-style upsert of profile fields (omitted collections clear to empty).",
  "properties": {
    "opt_out": {
      "type": "boolean"
    },
    "attributes": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/UserProfileAttribute"
      }
    },
    "tags": {
      "type": "array",
      "maxItems": 32,
      "items": {
        "type": "string",
        "maxLength": 256
      }
    },
    "segments": {
      "type": "array",
      "maxItems": 128,
      "items": {
        "type": "string",
        "maxLength": 256
      }
    }
  }
}
AttributionConfigUpdate

schemas/ProductAttributionMatchType

{
  "type": "object",
  "description": "Upsert payload; omitted fields keep their current (or default) values.",
  "properties": {
    "click_window_seconds": {
      "type": "integer",
      "minimum": 1,
      "maximum": 3888000
    },
    "view_window_seconds": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2592000
    },
    "view_through_enabled": {
      "type": "boolean"
    },
    "enabled": {
      "type": "boolean"
    },
    "product_attribution_match_type": {
      "$ref": "#/components/schemas/ProductAttributionMatchType"
    }
  }
}
EventTracker

{
  "type": "object",
  "description": "One third-party event tracker (docs/design/29-event-trackers.md; D47). url is HTTPS + macro-templated. vendor_key/verification_params/fallback_url apply only to verification_script kind.\n",
  "required": [
    "event",
    "kind",
    "url"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "event": {
      "type": "string",
      "enum": [
        "IMPRESSION",
        "BILLABLE_IMPRESSION",
        "CLICK",
        "START",
        "FIRST_QUARTILE",
        "MIDPOINT",
        "THIRD_QUARTILE",
        "COMPLETE",
        "MUTE",
        "PAUSE",
        "FULLSCREEN",
        "SKIP",
        "VIEWABLE_MRC50",
        "VIEWABLE_MRC100",
        "COMPANION_VIEW",
        "ERROR",
        "VIEW_UNDETERMINED"
      ]
    },
    "kind": {
      "type": "string",
      "enum": [
        "IMAGE_PIXEL",
        "JS_URL",
        "TRACKING_URL",
        "CLICK_REDIRECT",
        "CLICK_PARALLEL",
        "VERIFICATION_SCRIPT"
      ]
    },
    "url": {
      "type": "string",
      "description": "HTTPS, macro-templated."
    },
    "vendor_key": {
      "type": "string"
    },
    "verification_params": {
      "type": "string",
      "description": "Opaque OMID VerificationParameters JSON."
    },
    "fallback_url": {
      "type": "string",
      "description": "HTTPS no-JS fallback pixel (verification_script only)."
    }
  }
}
EventTrackerSet

schemas/EventTracker

{
  "type": "object",
  "description": "The full replacement set of an entity's event trackers.",
  "required": [
    "trackers"
  ],
  "properties": {
    "trackers": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/EventTracker"
      }
    }
  }
}
EventTrackerList

schemas/EventTracker

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/EventTracker"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
IvtPolicy

{
  "type": "object",
  "description": "Per-tenant IVT detection/enforcement policy (riptide.ivt.v1.IvtPolicy; docs/design/28-ivt-engine.md). Zero/empty values mean \"library default\".\n",
  "required": [
    "id",
    "tenant_id",
    "mode"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "mode": {
      "type": "string",
      "enum": [
        "",
        "OFF",
        "MONITOR",
        "ENFORCE"
      ]
    },
    "flag_threshold": {
      "type": "integer",
      "minimum": 0,
      "maximum": 1000
    },
    "block_threshold": {
      "type": "integer",
      "minimum": 0,
      "maximum": 1000
    },
    "allow_givt": {
      "type": "boolean"
    },
    "disabled_detectors": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "max_requests_per_ip_min": {
      "type": "integer",
      "minimum": 0
    },
    "max_fires_per_ip_min": {
      "type": "integer",
      "minimum": 0
    },
    "min_click_delay_ms": {
      "type": "integer",
      "minimum": 0
    },
    "supply_tolerance_pct": {
      "type": "string",
      "description": "Decimal percentage (e.g. \"1.5\"); empty disables tolerance blocking."
    },
    "supply_min_requests": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "min_supply_grade": {
      "type": "string",
      "enum": [
        "",
        "A",
        "B",
        "C",
        "D",
        "F"
      ]
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
IvtPolicyUpdate

{
  "type": "object",
  "properties": {
    "mode": {
      "type": "string",
      "enum": [
        "",
        "OFF",
        "MONITOR",
        "ENFORCE"
      ]
    },
    "flag_threshold": {
      "type": "integer",
      "minimum": 0,
      "maximum": 1000
    },
    "block_threshold": {
      "type": "integer",
      "minimum": 0,
      "maximum": 1000
    },
    "allow_givt": {
      "type": "boolean"
    },
    "disabled_detectors": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "max_requests_per_ip_min": {
      "type": "integer",
      "minimum": 0
    },
    "max_fires_per_ip_min": {
      "type": "integer",
      "minimum": 0
    },
    "min_click_delay_ms": {
      "type": "integer",
      "minimum": 0
    },
    "supply_tolerance_pct": {
      "type": "string"
    },
    "supply_min_requests": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "min_supply_grade": {
      "type": "string",
      "enum": [
        "",
        "A",
        "B",
        "C",
        "D",
        "F"
      ]
    }
  }
}
SupplyScorecard

{
  "type": "object",
  "description": "Computed quality fact for one supply key (publisher x domain/bundle) over one trailing window (riptide.ivt.v1.SupplyScorecard; docs/design/28-ivt-engine.md).\n",
  "required": [
    "id",
    "tenant_id",
    "publisher_public_id",
    "supply_id",
    "requests",
    "ivt_rate_pct",
    "grade"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "publisher_public_id": {
      "type": "string"
    },
    "supply_id": {
      "type": "string",
      "description": "Canonical domain-or-bundle half of the supply key."
    },
    "window_start": {
      "type": "string",
      "format": "date-time"
    },
    "window_end": {
      "type": "string",
      "format": "date-time"
    },
    "requests": {
      "type": "integer",
      "format": "int64"
    },
    "flagged": {
      "type": "integer",
      "format": "int64"
    },
    "blocked": {
      "type": "integer",
      "format": "int64"
    },
    "givt": {
      "type": "integer",
      "format": "int64"
    },
    "sivt": {
      "type": "integer",
      "format": "int64"
    },
    "ivt_rate_pct": {
      "type": "string",
      "description": "Decimal percentage, 4dp."
    },
    "grade": {
      "type": "string",
      "enum": [
        "",
        "A",
        "B",
        "C",
        "D",
        "F"
      ]
    },
    "top_reasons": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "computed_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
SupplyScorecardList

schemas/SupplyScorecard

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/SupplyScorecard"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
IpList

schemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "mode",
    "scope",
    "status",
    "version",
    "entry_count",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "mode": {
      "type": "string",
      "enum": [
        "block",
        "allow"
      ],
      "description": "block = exclude members (blocklist); allow = include-only when bound (allowlist). Primary binding is line-item targeting via ip_block_list_ids / ip_allow_list_ids.\n"
    },
    "scope": {
      "type": "string",
      "enum": [
        "tenant",
        "publisher",
        "cell"
      ],
      "description": "Optional request-wide shed: tenant/publisher post-resolve; cell at the serve edge (operator-only). Line items bind lists regardless of this field.\n"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "Required when scope=publisher; must be null otherwise."
    },
    "blob_uri": {
      "type": "string",
      "nullable": true,
      "description": "Object-storage URI of the compiled membership blob (set on publish)."
    },
    "content_hash": {
      "type": "string",
      "nullable": true,
      "description": "Hex SHA-256 of the compiled blob bytes."
    },
    "version": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "entry_count": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Approximate membership cardinality after last publish (hosts + CIDRs)."
    },
    "staging_count": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Uncompiled staging lines awaiting publish (not part of the live set)."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
IpListCreate

{
  "type": "object",
  "required": [
    "name",
    "mode",
    "scope"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "mode": {
      "type": "string",
      "enum": [
        "block",
        "allow"
      ]
    },
    "scope": {
      "type": "string",
      "enum": [
        "tenant",
        "publisher",
        "cell"
      ],
      "description": "cell is operator-only; publisher requires publisher_id owned by the tenant."
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Required when scope=publisher; must belong to the tenant."
    }
  }
}
IpListPage

schemas/IpList

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/IpList"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
IpListBulkImportRequest

{
  "type": "object",
  "required": [
    "lines"
  ],
  "properties": {
    "lines": {
      "type": "array",
      "minItems": 1,
      "maxItems": 10000,
      "items": {
        "type": "string"
      },
      "description": "One IP or CIDR per line (IPv4/IPv6). Empty lines and `#` comments are ignored server-side.\n"
    },
    "replace": {
      "type": "boolean",
      "default": false,
      "description": "When true, clear existing staging for this list before appending."
    }
  }
}
BidModifierTerm

{
  "type": "object",
  "required": [
    "dimension",
    "multiplier"
  ],
  "description": "One sparse match term on a bid modifier. Matching multipliers multiply; no match ⇒ 1.0; result clamped to [0,10]; 0 ⇒ no-bid (design 32 §4.3).\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Set on read; ignored on write (server-assigned)."
    },
    "dimension": {
      "type": "string",
      "minLength": 1
    },
    "key": {
      "type": "string",
      "default": ""
    },
    "value": {
      "type": "string",
      "default": ""
    },
    "multiplier": {
      "type": "string",
      "description": "Decimal string in [0, 10], e.g. \"1.2500\"."
    }
  }
}
BidModifierTermInput

{
  "type": "object",
  "required": [
    "dimension",
    "multiplier"
  ],
  "properties": {
    "dimension": {
      "type": "string",
      "minLength": 1
    },
    "key": {
      "type": "string",
      "default": ""
    },
    "value": {
      "type": "string",
      "default": ""
    },
    "multiplier": {
      "type": "string",
      "description": "Decimal string in [0, 10]."
    }
  }
}
BidModifier

schemas/BidModifierTermschemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "active",
    "terms",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "Tenant-scoped sparse multiplicative bid adjustment set (design 32 §4.3 / D51). Max 1000 terms; attach via line_item.bid_modifier_id.\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "active": {
      "type": "boolean"
    },
    "terms": {
      "type": "array",
      "maxItems": 1000,
      "items": {
        "$ref": "#/components/schemas/BidModifierTerm"
      }
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
BidModifierCreate

schemas/BidModifierTermInput

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "active": {
      "type": "boolean",
      "default": true
    },
    "terms": {
      "type": "array",
      "maxItems": 1000,
      "items": {
        "$ref": "#/components/schemas/BidModifierTermInput"
      }
    }
  }
}
BidModifierUpdate

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "active": {
      "type": "boolean"
    }
  }
}
BidModifierTermsReplace

schemas/BidModifierTermInput

{
  "type": "object",
  "required": [
    "terms"
  ],
  "properties": {
    "terms": {
      "type": "array",
      "maxItems": 1000,
      "items": {
        "$ref": "#/components/schemas/BidModifierTermInput"
      }
    }
  }
}
BidModifierPage

schemas/BidModifier

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/BidModifier"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
CustomListKind

{
  "type": "string",
  "description": "Request dimension a custom list matches (design 32 §6.1). LAT_LONG is exact \"lat,lon\" string match in v1.\n",
  "enum": [
    "DOMAIN",
    "APP_BUNDLE",
    "SITE",
    "PUBLISHER_REF",
    "DEAL_REF",
    "ZIP",
    "LAT_LONG"
  ]
}
CustomList

schemas/CustomListKindschemas/EntityUsageschemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "kind",
    "items",
    "entry_count",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "Tenant membership set for non-IP targeting (design 32 §6.1 / BP-LISTS). Max 10000 items embedded in the serving plan; attach via line_item.custom_block_list_ids / custom_allow_list_ids.\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "kind": {
      "$ref": "#/components/schemas/CustomListKind"
    },
    "items": {
      "type": "array",
      "maxItems": 10000,
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "entry_count": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "usage": {
      "readOnly": true,
      "description": "Where the list is referenced (line items via custom_block_list_ids / custom_allow_list_ids; creatives and placements are 0 for lists); counted at read time.",
      "allOf": [
        {
          "$ref": "#/components/schemas/EntityUsage"
        }
      ]
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
CustomListCreate

schemas/CustomListKind

{
  "type": "object",
  "required": [
    "name",
    "kind"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "kind": {
      "$ref": "#/components/schemas/CustomListKind"
    },
    "items": {
      "type": "array",
      "maxItems": 10000,
      "items": {
        "type": "string",
        "minLength": 1
      }
    }
  }
}
CustomListUpdate

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    }
  }
}
CustomListItemsReplace

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "maxItems": 10000,
      "items": {
        "type": "string",
        "minLength": 1
      }
    }
  }
}
CustomListPage

schemas/CustomList

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CustomList"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
CreativeTemplateKind

{
  "type": "string",
  "enum": [
    "DISPLAY",
    "NATIVE",
    "VAST"
  ]
}
CreativeTemplate

schemas/CreativeTemplateKindschemas/CreativeTemplateRefreshStatusschemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "kind",
    "markup_template",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "Tenant creative template (design 32 §6.2 / CP-5 thin). markup_template uses {{MACRO}} tokens; optional schema_json documents required template_fields keys.\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "kind": {
      "$ref": "#/components/schemas/CreativeTemplateKind"
    },
    "markup_template": {
      "type": "string"
    },
    "schema_json": {
      "type": "string",
      "description": "Optional shallow JSON Schema text; empty = none."
    },
    "refresh_interval_seconds": {
      "type": "integer",
      "nullable": true,
      "minimum": 300,
      "description": "Dynamic-creative refresh cadence in seconds (SR-1218 DCO refresh; minimum 300). Null / omitted = no scheduled refresh; refreshCreativeTemplate still runs on demand.\n"
    },
    "refresh_source_url": {
      "type": "string",
      "format": "uri",
      "nullable": true,
      "maxLength": 2048,
      "description": "HTTPS feed the refresh run fetches to re-expand template variants (SR-1218). Null / omitted = the template is static and cannot be refreshed.\n"
    },
    "refresh_status": {
      "$ref": "#/components/schemas/CreativeTemplateRefreshStatus"
    },
    "last_refreshed_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "readOnly": true,
      "description": "When the last refresh run finished successfully; null until one has."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
CreativeTemplateCreate

schemas/CreativeTemplateKind

{
  "type": "object",
  "required": [
    "name",
    "kind"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "kind": {
      "$ref": "#/components/schemas/CreativeTemplateKind"
    },
    "markup_template": {
      "type": "string"
    },
    "schema_json": {
      "type": "string"
    },
    "refresh_interval_seconds": {
      "type": "integer",
      "nullable": true,
      "minimum": 300,
      "description": "Dynamic-creative refresh cadence in seconds (SR-1218 DCO refresh; minimum 300). Null / omitted = no scheduled refresh; refreshCreativeTemplate still runs on demand.\n"
    },
    "refresh_source_url": {
      "type": "string",
      "format": "uri",
      "nullable": true,
      "maxLength": 2048,
      "description": "HTTPS feed the refresh run fetches to re-expand template variants (SR-1218). Null / omitted = the template is static and cannot be refreshed.\n"
    }
  }
}
CreativeTemplateUpdate

schemas/CreativeTemplateKind

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "kind": {
      "$ref": "#/components/schemas/CreativeTemplateKind"
    },
    "markup_template": {
      "type": "string"
    },
    "schema_json": {
      "type": "string"
    },
    "refresh_interval_seconds": {
      "type": "integer",
      "nullable": true,
      "minimum": 300,
      "description": "Dynamic-creative refresh cadence in seconds (SR-1218 DCO refresh; minimum 300). Null / omitted = no scheduled refresh; refreshCreativeTemplate still runs on demand.\n"
    },
    "refresh_source_url": {
      "type": "string",
      "format": "uri",
      "nullable": true,
      "maxLength": 2048,
      "description": "HTTPS feed the refresh run fetches to re-expand template variants (SR-1218). Null / omitted = the template is static and cannot be refreshed.\n"
    }
  }
}
CreativeTemplatePage

schemas/CreativeTemplate

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CreativeTemplate"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
CreativeTemplateRefreshStatus

{
  "type": "string",
  "description": "Dynamic-creative refresh state of a template (SR-1218), read-only (advanced by refreshCreativeTemplate and the scheduled cadence): IDLE when no source is configured or no run is pending, SCHEDULED when the cadence has queued a run, RUNNING while one runs, FAILED when the last run failed (last_refreshed_at keeps the previous success).\n",
  "enum": [
    "IDLE",
    "SCHEDULED",
    "RUNNING",
    "FAILED"
  ],
  "x-enum-varnames": [
    "CreativeTemplateRefreshStatusIDLE",
    "CreativeTemplateRefreshStatusSCHEDULED",
    "CreativeTemplateRefreshStatusRUNNING",
    "CreativeTemplateRefreshStatusFAILED"
  ]
}
CreativeTemplateRefreshRunStatus

{
  "type": "string",
  "description": "Outcome of one refresh run (SR-1218).",
  "enum": [
    "RUNNING",
    "SUCCEEDED",
    "FAILED"
  ],
  "x-enum-varnames": [
    "CreativeTemplateRefreshRunStatusRUNNING",
    "CreativeTemplateRefreshRunStatusSUCCEEDED",
    "CreativeTemplateRefreshRunStatusFAILED"
  ]
}
CreativeTemplateRefreshRun

schemas/CreativeTemplateRefreshRunStatus

{
  "type": "object",
  "description": "One dynamic-creative refresh run (SR-1218; creative_template_refresh_run): started by refreshCreativeTemplate or the scheduled cadence, it re-expands every creative variant rendered from the template against the fresh refresh_source_url feed.\n",
  "required": [
    "id",
    "creative_template_id",
    "started_at",
    "status",
    "variants_refreshed"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Run id."
    },
    "creative_template_id": {
      "type": "string",
      "format": "uuid",
      "description": "The template refreshed."
    },
    "started_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the run started."
    },
    "finished_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the run finished (SUCCEEDED or FAILED); null while RUNNING."
    },
    "status": {
      "$ref": "#/components/schemas/CreativeTemplateRefreshRunStatus"
    },
    "error": {
      "type": "string",
      "nullable": true,
      "description": "Failure reason when status is FAILED (fetch error, feed shape, variant render); null otherwise."
    },
    "variants_refreshed": {
      "type": "integer",
      "minimum": 0,
      "description": "Number of creative variants re-expanded so far (final on SUCCEEDED)."
    }
  }
}
DeliveryExperimentArm

{
  "type": "string",
  "enum": [
    "CONTROL",
    "TREATMENT"
  ],
  "description": "Sticky user arm (design 32 §8.1). CONTROL suppresses TREATMENT subjects."
}
DeliveryExperimentSubjectKind

{
  "type": "string",
  "enum": [
    "CAMPAIGN_ORDER",
    "LINE_ITEM"
  ]
}
DeliveryExperimentSubject

schemas/DeliveryExperimentSubjectKindschemas/DeliveryExperimentArm

{
  "type": "object",
  "required": [
    "subject_id",
    "kind",
    "arm"
  ],
  "properties": {
    "subject_id": {
      "type": "string",
      "format": "uuid"
    },
    "kind": {
      "$ref": "#/components/schemas/DeliveryExperimentSubjectKind"
    },
    "arm": {
      "$ref": "#/components/schemas/DeliveryExperimentArm"
    }
  }
}
DeliveryExperiment

schemas/DeliveryExperimentSubjectschemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "holdout_pct",
    "subjects",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "Tenant holdout/campaign experiment (design 32 §8.1 / BP-EXP). holdout_pct is the percent of sticky users in CONTROL; control arm suppresses TREATMENT subjects.\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "holdout_pct": {
      "type": "string",
      "description": "Decimal percent 0–100 (4 dp money style), e.g. \"10.0000\"."
    },
    "subjects": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DeliveryExperimentSubject"
      }
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DeliveryExperimentCreate

schemas/DeliveryExperimentSubject

{
  "type": "object",
  "required": [
    "name",
    "holdout_pct"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "holdout_pct": {
      "type": "string",
      "minLength": 1
    },
    "subjects": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DeliveryExperimentSubject"
      }
    }
  }
}
DeliveryExperimentUpdate

{
  "type": "object",
  "required": [
    "name",
    "holdout_pct"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "holdout_pct": {
      "type": "string",
      "minLength": 1
    }
  }
}
DeliveryExperimentSubjectsReplace

schemas/DeliveryExperimentSubject

{
  "type": "object",
  "required": [
    "subjects"
  ],
  "properties": {
    "subjects": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DeliveryExperimentSubject"
      }
    }
  }
}
DeliveryExperimentPage

schemas/DeliveryExperiment

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DeliveryExperiment"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
DeliveryAlertMetric

{
  "type": "string",
  "enum": [
    "SPEND",
    "IMPRESSIONS",
    "PACE"
  ],
  "description": "SPEND/IMPRESSIONS are window sums; PACE is (actual/expected)*100 percent (design 32 §8.2).\n"
}
DeliveryAlertComparison

{
  "type": "string",
  "enum": [
    "ABOVE",
    "BELOW"
  ]
}
DeliveryAlertRule

schemas/DeliveryAlertMetricschemas/DeliveryAlertComparisonschemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "metric",
    "comparison",
    "threshold",
    "window_seconds",
    "enabled",
    "cooldown_seconds",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "Tenant delivery/spend alert rule (design 32 §8.2 / BP-ALERT). HMAC secrets are stored only as webhook_secret_ref (secret store / RIPTIDE_WEBHOOK_SECRETS); never returned on GET/list.\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "metric": {
      "$ref": "#/components/schemas/DeliveryAlertMetric"
    },
    "comparison": {
      "$ref": "#/components/schemas/DeliveryAlertComparison"
    },
    "threshold": {
      "type": "string",
      "description": "Decimal threshold (4 dp); money for SPEND, count for IMPRESSIONS, percent for PACE."
    },
    "window_seconds": {
      "type": "integer",
      "minimum": 1
    },
    "campaign_order_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "line_item_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "webhook_url": {
      "type": "string"
    },
    "webhook_configured": {
      "type": "boolean",
      "description": "True when a webhook_secret_ref is stored (secret itself is never returned)."
    },
    "enabled": {
      "type": "boolean"
    },
    "cooldown_seconds": {
      "type": "integer",
      "minimum": 0
    },
    "last_fired_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true
    },
    "muted_until": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "While in the future the rule is evaluated but never fires (UX-41 mute)."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DeliveryAlertMuteRequest

{
  "type": "object",
  "properties": {
    "muted_until": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "Mute until this instant (must be in the future); null or omitted unmutes."
    }
  }
}
DeliveryAlertRuleCreated

schemas/DeliveryAlertRule

{
  "allOf": [
    {
      "$ref": "#/components/schemas/DeliveryAlertRule"
    },
    {
      "type": "object",
      "properties": {
        "webhook_secret_ref": {
          "type": "string",
          "description": "Echoed on create when a new secret_ref is supplied (not the secret value)."
        }
      }
    }
  ]
}
DeliveryAlertRuleCreate

schemas/DeliveryAlertMetricschemas/DeliveryAlertComparison

{
  "type": "object",
  "required": [
    "name",
    "metric",
    "comparison",
    "threshold",
    "window_seconds"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "metric": {
      "$ref": "#/components/schemas/DeliveryAlertMetric"
    },
    "comparison": {
      "$ref": "#/components/schemas/DeliveryAlertComparison"
    },
    "threshold": {
      "type": "string",
      "minLength": 1
    },
    "window_seconds": {
      "type": "integer",
      "minimum": 1
    },
    "campaign_order_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "line_item_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "webhook_url": {
      "type": "string",
      "description": "HTTPS URL only; localhost/RFC1918/metadata hosts are rejected."
    },
    "webhook_secret_ref": {
      "type": "string",
      "description": "Secret-store reference resolved at fire time via SecretResolver (RIPTIDE_WEBHOOK_SECRETS JSON map). Never persist the raw HMAC secret in the rule row.\n"
    },
    "enabled": {
      "type": "boolean"
    },
    "cooldown_seconds": {
      "type": "integer",
      "minimum": 0
    }
  }
}
DeliveryAlertRuleUpdate

schemas/DeliveryAlertMetricschemas/DeliveryAlertComparison

{
  "type": "object",
  "required": [
    "name",
    "metric",
    "comparison",
    "threshold",
    "window_seconds"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "metric": {
      "$ref": "#/components/schemas/DeliveryAlertMetric"
    },
    "comparison": {
      "$ref": "#/components/schemas/DeliveryAlertComparison"
    },
    "threshold": {
      "type": "string",
      "minLength": 1
    },
    "window_seconds": {
      "type": "integer",
      "minimum": 1
    },
    "campaign_order_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "line_item_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "webhook_url": {
      "type": "string",
      "description": "HTTPS URL only; localhost/RFC1918/metadata hosts are rejected."
    },
    "webhook_secret_ref": {
      "type": "string",
      "description": "Omit or empty to leave the stored secret_ref unchanged."
    },
    "enabled": {
      "type": "boolean"
    },
    "cooldown_seconds": {
      "type": "integer",
      "minimum": 0
    }
  }
}
DeliveryAlertRulePage

schemas/DeliveryAlertRule

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DeliveryAlertRule"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
DeliveryAlertWebhookStatus

{
  "type": "string",
  "enum": [
    "SENT",
    "SKIPPED",
    "FAILED"
  ]
}
DeliveryAlertEvent

schemas/DeliveryAlertMetricschemas/DeliveryAlertComparisonschemas/DeliveryAlertWebhookStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "rule_id",
    "metric",
    "observed_value",
    "threshold",
    "comparison",
    "fired_at",
    "webhook_status"
  ],
  "description": "Append-only alert firing record (design 32 §8.2).",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "rule_id": {
      "type": "string",
      "format": "uuid"
    },
    "metric": {
      "$ref": "#/components/schemas/DeliveryAlertMetric"
    },
    "observed_value": {
      "type": "string"
    },
    "threshold": {
      "type": "string"
    },
    "comparison": {
      "$ref": "#/components/schemas/DeliveryAlertComparison"
    },
    "fired_at": {
      "type": "string",
      "format": "date-time"
    },
    "webhook_status": {
      "$ref": "#/components/schemas/DeliveryAlertWebhookStatus"
    },
    "acknowledged_at": {
      "type": "string",
      "format": "date-time",
      "description": "Set by acknowledgeDeliveryAlertEvent (UX-41)."
    },
    "acknowledged_by": {
      "type": "string",
      "description": "Actor label that acknowledged the firing."
    }
  }
}
DeliveryAlertEventPage

schemas/DeliveryAlertEvent

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DeliveryAlertEvent"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ProductAttributionMatchType

{
  "type": "string",
  "description": "Catalog-aware attribution match (design 35 §5 / CP-8). Mirrors riptide.common.v1.ProductAttributionMatchType.\n",
  "enum": [
    "ANY",
    "PRODUCT",
    "BRAND",
    "CATEGORY",
    "MERCHANT"
  ]
}
ItemCatalog

schemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "currency",
    "locale",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "Tenant product/SKU catalog container (design 35 / CP-6). Distinct from MarketplaceListing (open-marketplace discovery).\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "locale": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ItemCatalogCreate

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "locale": {
      "type": "string"
    }
  }
}
ItemCatalogUpdate

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "locale": {
      "type": "string"
    }
  }
}
ItemCatalogPage

schemas/ItemCatalog

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ItemCatalog"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
CatalogItem

schemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "catalog_id",
    "external_item_id",
    "title",
    "available",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "SKU/product row in an ItemCatalog (design 35). external_item_id is the merchant/product id unique per (tenant, catalog).\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "catalog_id": {
      "type": "string",
      "format": "uuid"
    },
    "external_item_id": {
      "type": "string",
      "minLength": 1
    },
    "title": {
      "type": "string"
    },
    "brand": {
      "type": "string"
    },
    "category": {
      "type": "string"
    },
    "merchant_id": {
      "type": "string"
    },
    "price": {
      "type": "string",
      "description": "Decimal string money (4 dp)."
    },
    "currency": {
      "type": "string"
    },
    "available": {
      "type": "boolean"
    },
    "image_url": {
      "type": "string"
    },
    "product_url": {
      "type": "string"
    },
    "attributes": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
CatalogItemInput

schemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "external_item_id"
  ],
  "properties": {
    "external_item_id": {
      "type": "string",
      "minLength": 1
    },
    "title": {
      "type": "string"
    },
    "brand": {
      "type": "string"
    },
    "category": {
      "type": "string"
    },
    "merchant_id": {
      "type": "string"
    },
    "price": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "available": {
      "type": "boolean"
    },
    "image_url": {
      "type": "string"
    },
    "product_url": {
      "type": "string"
    },
    "attributes": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    }
  }
}
CatalogItemUpsert

schemas/CatalogItemInput

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1000,
      "items": {
        "$ref": "#/components/schemas/CatalogItemInput"
      }
    }
  }
}
CatalogItemPage

schemas/CatalogItem

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CatalogItem"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ExportDestinationKind

{
  "type": "string",
  "description": "Object-store destination kind (design 37 §2 / CP-9).",
  "enum": [
    "S3",
    "GCS"
  ]
}
ExportDestination

schemas/ExportDestinationKindschemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "kind",
    "bucket",
    "format",
    "enabled",
    "status",
    "created_at",
    "updated_at"
  ],
  "description": "Tenant-owned event export destination. Credentials via secret_ref (secret store).\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "kind": {
      "$ref": "#/components/schemas/ExportDestinationKind"
    },
    "bucket": {
      "type": "string",
      "minLength": 1
    },
    "prefix": {
      "type": "string"
    },
    "region": {
      "type": "string"
    },
    "secret_ref": {
      "type": "string",
      "description": "Secret-store reference for destination credentials (never plaintext)."
    },
    "format": {
      "type": "string",
      "enum": [
        "JSONL",
        "PARQUET"
      ],
      "description": "File encoding (docs/spec/export-record.md). Files are written hourly under {prefix}/{tenant_id}/dt=YYYY-MM-DD/hour=HH/ in either format.\n"
    },
    "event_kinds": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Empty = all kinds; otherwise filter (e.g. IMPRESSION, CLICK)."
    },
    "enabled": {
      "type": "boolean"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ExportDestinationCreate

schemas/ExportDestinationKind

{
  "type": "object",
  "required": [
    "name",
    "kind",
    "bucket"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "kind": {
      "$ref": "#/components/schemas/ExportDestinationKind"
    },
    "bucket": {
      "type": "string",
      "minLength": 1
    },
    "prefix": {
      "type": "string"
    },
    "region": {
      "type": "string"
    },
    "secret_ref": {
      "type": "string"
    },
    "format": {
      "type": "string",
      "enum": [
        "JSONL",
        "PARQUET"
      ]
    },
    "event_kinds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "enabled": {
      "type": "boolean"
    }
  }
}
ExportDestinationUpdate

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "bucket": {
      "type": "string",
      "minLength": 1
    },
    "prefix": {
      "type": "string"
    },
    "region": {
      "type": "string"
    },
    "secret_ref": {
      "type": "string"
    },
    "format": {
      "type": "string",
      "enum": [
        "JSONL",
        "PARQUET"
      ]
    },
    "event_kinds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "enabled": {
      "type": "boolean"
    }
  }
}
ExportDestinationPage

schemas/ExportDestination

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ExportDestination"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ExportJobKind

{
  "type": "string",
  "description": "Customer log export kind (maps to telemetry EventKind / attributed_conversion).",
  "enum": [
    "WINS",
    "IMPRESSIONS",
    "CLICKS",
    "CONVERSIONS",
    "BIDS"
  ]
}
ExportJobStatus

{
  "type": "string",
  "enum": [
    "PENDING",
    "RUNNING",
    "SUCCEEDED",
    "FAILED",
    "ARCHIVED"
  ]
}
ExportJobFormat

{
  "type": "string",
  "enum": [
    "JSONL",
    "CSV"
  ]
}
ExportJob

schemas/ExportJobKindschemas/ExportJobFormatschemas/ExportJobStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "kind",
    "format",
    "range_start",
    "range_end",
    "status",
    "row_count",
    "created_at",
    "updated_at"
  ],
  "description": "On-demand customer log export job (BP-LOGS). Worker writes JSONL/CSV to blobstore and sets blob_uri (mem:// or s3://). Empty history is SUCCEEDED with row_count 0.\n",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "kind": {
      "$ref": "#/components/schemas/ExportJobKind"
    },
    "format": {
      "$ref": "#/components/schemas/ExportJobFormat"
    },
    "range_start": {
      "type": "string",
      "format": "date-time"
    },
    "range_end": {
      "type": "string",
      "format": "date-time"
    },
    "status": {
      "$ref": "#/components/schemas/ExportJobStatus"
    },
    "blob_uri": {
      "type": "string",
      "description": "Object-store URI after SUCCEEDED (empty while PENDING/RUNNING)."
    },
    "row_count": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "error_message": {
      "type": "string"
    },
    "destination_id": {
      "type": "string",
      "format": "uuid",
      "description": "The tenant export_destination the file was written through (SR-1214); absent when the job wrote to the platform blobstore.\n"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    },
    "completed_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ExportJobCreate

schemas/ExportJobKindschemas/ExportJobFormat

{
  "type": "object",
  "required": [
    "kind",
    "range_start",
    "range_end"
  ],
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/ExportJobKind"
    },
    "format": {
      "$ref": "#/components/schemas/ExportJobFormat"
    },
    "range_start": {
      "type": "string",
      "format": "date-time"
    },
    "range_end": {
      "type": "string",
      "format": "date-time"
    },
    "destination_id": {
      "type": "string",
      "format": "uuid",
      "description": "Optional tenant export_destination (same tenant, ACTIVE) to write the file to through libs/export.ResolveWriter — its credentials come from the destination's secret_ref. Omit to write to the platform blobstore (mem:// or s3:// blob_uri).\n"
    }
  }
}
ExportJobPage

schemas/ExportJob

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ExportJob"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
AdvertiserReportSummary

{
  "type": "object",
  "required": [
    "tenant_id",
    "advertiser_id",
    "impressions",
    "clicks",
    "spend"
  ],
  "description": "Minimal onsite advertiser portal read model (design 37 §3 / CP-10). Counts are zero when no reporting source is wired; scaffold for branded portal surfaces.\n",
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid"
    },
    "impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "clicks": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "spend": {
      "type": "string",
      "description": "Decimal string money (4 dp) in tenant reporting currency."
    },
    "currency": {
      "type": "string"
    }
  }
}
TenantOIDCConfig

{
  "type": "object",
  "required": [
    "tenant_id",
    "enabled"
  ],
  "description": "Tenant OIDC SSO config entity (design 37 §5 / CP-15). Client secret via client_secret_ref in the secret store — never plaintext in this API.\n",
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "enabled": {
      "type": "boolean"
    },
    "issuer_url": {
      "type": "string"
    },
    "client_id": {
      "type": "string"
    },
    "client_secret_ref": {
      "type": "string"
    },
    "scopes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "role_claim": {
      "type": "string",
      "description": "IdP claim mapped to Riptide roles."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
TenantOIDCConfigUpdate

{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "issuer_url": {
      "type": "string"
    },
    "client_id": {
      "type": "string"
    },
    "client_secret_ref": {
      "type": "string"
    },
    "scopes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "role_claim": {
      "type": "string"
    }
  }
}
TenantSAMLConfig

{
  "type": "object",
  "required": [
    "tenant_id",
    "enabled"
  ],
  "description": "Tenant SAML SSO config scaffold (design 37 §5 / CP-15). IdP signing certificate via cert_ref in the secret store — never plaintext in this API. Assertion login residual.\n",
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "enabled": {
      "type": "boolean"
    },
    "entity_id": {
      "type": "string",
      "description": "IdP entity ID / issuer."
    },
    "sso_url": {
      "type": "string",
      "description": "IdP HTTP-Redirect SSO URL."
    },
    "cert_ref": {
      "type": "string",
      "description": "Secret-store ref for IdP X.509 cert PEM."
    },
    "role_claim": {
      "type": "string",
      "description": "IdP attribute mapped to Riptide roles."
    },
    "email_attribute": {
      "type": "string",
      "description": "IdP attribute carrying the user's email; empty = the assertion NameID (email format)."
    },
    "sp_entity_id": {
      "type": "string",
      "description": "This deployment's SP entity id (the metadata URL), read-only."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
TenantSAMLConfigUpdate

{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    },
    "entity_id": {
      "type": "string"
    },
    "sso_url": {
      "type": "string"
    },
    "cert_ref": {
      "type": "string"
    },
    "role_claim": {
      "type": "string"
    },
    "email_attribute": {
      "type": "string"
    }
  }
}
AdvertiserLineItemWrite

schemas/DeliveryGoalTypeschemas/DemandRateType

{
  "type": "object",
  "description": "Limited self-serve line-item fields for the onsite advertiser portal (CP-10): name, owning campaign_order_id (create), flight window, delivery goal, and rate.\n",
  "properties": {
    "campaign_order_id": {
      "type": "string",
      "format": "uuid",
      "description": "Required on create; must belong to the path advertiser_id."
    },
    "name": {
      "type": "string"
    },
    "start_at": {
      "type": "string",
      "format": "date-time"
    },
    "end_at": {
      "type": "string",
      "format": "date-time"
    },
    "goal_type": {
      "$ref": "#/components/schemas/DeliveryGoalType"
    },
    "lifetime_goal": {
      "type": "integer",
      "format": "int64"
    },
    "daily_goal": {
      "type": "integer",
      "format": "int64"
    },
    "rate_amount": {
      "type": "string",
      "description": "Buy rate (4dp decimal string)."
    },
    "demand_rate_type": {
      "$ref": "#/components/schemas/DemandRateType"
    },
    "cpm": {
      "type": "string",
      "description": "Legacy CPM alias when demand_rate_type is CPM."
    }
  }
}
IpListBulkImportResponse

{
  "type": "object",
  "required": [
    "accepted",
    "rejected",
    "staging_count"
  ],
  "properties": {
    "accepted": {
      "type": "integer",
      "minimum": 0
    },
    "rejected": {
      "type": "integer",
      "minimum": 0
    },
    "staging_count": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Staging lines present after this import."
    },
    "errors": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "index",
          "message"
        ],
        "properties": {
          "index": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  }
}
Placement

schemas/LifecycleStatusschemas/AdminPricingschemas/AdminCpmCapschemas/EntityVerificationschemas/WarmPoolConfigschemas/DualModeConfigschemas/StitchConfigschemas/DemandAttachmentConfigschemas/DealAuctionTypeschemas/CompanionSlotSpecschemas/LiveStreamConfig

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "public_id",
    "name",
    "delivery",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "public_id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "delivery": {
      "type": "string",
      "enum": [
        "WEB",
        "CTV",
        "APP",
        "DOOH"
      ]
    },
    "media": {
      "type": "string",
      "enum": [
        "VIDEO",
        "AUDIO",
        "BANNER"
      ]
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "floor": {
      "type": "string"
    },
    "pod_floor": {
      "type": "string"
    },
    "pricing": {
      "$ref": "#/components/schemas/AdminPricing"
    },
    "line_item_margin": {
      "type": "string"
    },
    "cpm_cap": {
      "$ref": "#/components/schemas/AdminCpmCap"
    },
    "upstream_cpm_cap": {
      "$ref": "#/components/schemas/AdminCpmCap"
    },
    "qps_limit": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "pod_enabled": {
      "type": "boolean"
    },
    "max_ad_duration": {
      "type": "integer",
      "minimum": 0
    },
    "max_pod_slots": {
      "type": "integer",
      "minimum": 0
    },
    "min_pod_duration": {
      "type": "integer",
      "minimum": 0
    },
    "max_pod_duration": {
      "type": "integer",
      "minimum": 0
    },
    "dedup_advertiser": {
      "type": "boolean"
    },
    "dedup_media": {
      "type": "boolean"
    },
    "dedup_category": {
      "type": "boolean"
    },
    "multi_imp": {
      "type": "boolean"
    },
    "packed_pixels": {
      "type": "boolean",
      "description": "Packed pixels (SR-1210 / SR-902, design 29 \"Rendering\"): true renders one platform beacon per event and the beacon fans the vendor tracker set out server-side from the sealed payload; false (default) renders every vendor URL into the document.\n"
    },
    "compliance_exempt": {
      "type": "boolean",
      "description": "When true (the default for new placements) the placement is exempt from the partner approval gate (route_approval / app approvals): demand routes and deals serve on it without a per-partner approval record. False makes the gate blocking.\n"
    },
    "ignore_compliance": {
      "type": "boolean",
      "deprecated": true,
      "description": "Deprecated since Wave 8 round 2 - alias of `compliance_exempt`, accepted and echoed for one release after CHANGELOG-api.md lists it; use `compliance_exempt`."
    },
    "blocked_advertisers": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "blocked_categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "allowed_advertisers": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 253
      },
      "description": "Advertiser allow-list for this placement (SR-1217; exact or parent-domain match). Non-empty overrides the publisher's allowed_advertisers; empty falls through to it.\n"
    },
    "vast_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /vast answers an empty VAST document (reason `vast_paused`) for this placement."
    },
    "ortb_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /ortb answers no-bid (reason `ortb_paused`) for this placement."
    },
    "blocked_exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels blocked on this placement (GC-03): a line item whose effective exclusion labels (union of advertiser, campaign order, and line item) intersect this set is ineligible here.\n"
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "warm_pool": {
      "$ref": "#/components/schemas/WarmPoolConfig"
    },
    "dual_mode": {
      "$ref": "#/components/schemas/DualModeConfig"
    },
    "stitch": {
      "$ref": "#/components/schemas/StitchConfig"
    },
    "demand_attachment": {
      "$ref": "#/components/schemas/DemandAttachmentConfig"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400,
      "description": "Supply-side delivery window override (seconds); precedence over publisher/tenant."
    },
    "line_item_ttl_minutes": {
      "type": "integer",
      "minimum": 5,
      "maximum": 1440,
      "description": "Direct line-item beacon validity (minutes); default 60 when unset."
    },
    "remainder_pct": {
      "type": "integer",
      "minimum": 0,
      "maximum": 99,
      "description": "CP-17 selection exploration percent (0–99). With that probability the single-winner path serves a uniform draw from non-primary eligible candidates. Omit/null = unset (no placement override of AuctionParams.RemainderPct).\n"
    },
    "auction_type": {
      "$ref": "#/components/schemas/DealAuctionType"
    },
    "companion_slots": {
      "type": "array",
      "maxItems": 8,
      "items": {
        "$ref": "#/components/schemas/CompanionSlotSpec"
      },
      "description": "Companion ad slots the placement's player can render (SR-1211): a creative's companions are matched to these by size; a `required` slot with no matching companion makes the creative ineligible here. Arrays present on update replace the full set.\n"
    },
    "live_stream": {
      "nullable": true,
      "description": "Live-stream insertion settings (SR-1211 / design 38). On update, omitted = unchanged and an explicit null clears them (the DemandPartner nullable-clears rule).",
      "allOf": [
        {
          "$ref": "#/components/schemas/LiveStreamConfig"
        }
      ]
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning publisher (SR-1010); scopes the publisher portal, per-publisher reporting and payout statements."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
PlacementCreate

schemas/AdminPricingschemas/AdminCpmCapschemas/EntityVerificationschemas/WarmPoolConfigschemas/DualModeConfigschemas/StitchConfigschemas/DemandAttachmentConfigschemas/DealAuctionTypeschemas/CompanionSlotSpecschemas/LiveStreamConfig

{
  "example": {
    "public_id": "acme-preroll",
    "name": "Acme web pre-roll",
    "publisher_id": "7a1d3c5e-2b4f-4c6d-8e9f-0a1b2c3d4e5f",
    "delivery": "WEB",
    "media": "VIDEO",
    "floor": "1.00",
    "max_ad_duration": 30
  },
  "type": "object",
  "required": [
    "public_id",
    "name",
    "delivery"
  ],
  "properties": {
    "public_id": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning publisher; must be an active publisher in the same tenant."
    },
    "delivery": {
      "type": "string",
      "enum": [
        "WEB",
        "CTV",
        "APP",
        "DOOH"
      ]
    },
    "media": {
      "type": "string",
      "enum": [
        "VIDEO",
        "AUDIO",
        "BANNER"
      ]
    },
    "floor": {
      "type": "string"
    },
    "pod_floor": {
      "type": "string"
    },
    "pricing": {
      "$ref": "#/components/schemas/AdminPricing"
    },
    "line_item_margin": {
      "type": "string"
    },
    "cpm_cap": {
      "$ref": "#/components/schemas/AdminCpmCap"
    },
    "upstream_cpm_cap": {
      "$ref": "#/components/schemas/AdminCpmCap"
    },
    "qps_limit": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "pod_enabled": {
      "type": "boolean"
    },
    "max_ad_duration": {
      "type": "integer",
      "minimum": 0
    },
    "max_pod_slots": {
      "type": "integer",
      "minimum": 0
    },
    "min_pod_duration": {
      "type": "integer",
      "minimum": 0
    },
    "max_pod_duration": {
      "type": "integer",
      "minimum": 0
    },
    "dedup_advertiser": {
      "type": "boolean"
    },
    "dedup_media": {
      "type": "boolean"
    },
    "dedup_category": {
      "type": "boolean"
    },
    "multi_imp": {
      "type": "boolean"
    },
    "packed_pixels": {
      "type": "boolean",
      "description": "Packed pixels (SR-1210 / SR-902, design 29 \"Rendering\"): true renders one platform beacon per event and the beacon fans the vendor tracker set out server-side from the sealed payload; false (default) renders every vendor URL into the document.\n"
    },
    "compliance_exempt": {
      "type": "boolean",
      "description": "Partner-approval gate exemption; see Placement.compliance_exempt."
    },
    "ignore_compliance": {
      "type": "boolean",
      "deprecated": true,
      "description": "Deprecated since Wave 8 round 2: alias of `compliance_exempt`, accepted and echoed for one release after CHANGELOG-api.md lists it; use `compliance_exempt`."
    },
    "blocked_advertisers": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "blocked_categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "allowed_advertisers": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 253
      },
      "description": "Advertiser allow-list for this placement (SR-1217; exact or parent-domain match). Non-empty overrides the publisher's allowed_advertisers; empty falls through to it.\n"
    },
    "vast_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /vast answers an empty VAST document (reason `vast_paused`) for this placement."
    },
    "ortb_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /ortb answers no-bid (reason `ortb_paused`) for this placement."
    },
    "blocked_exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels blocked on this placement (GC-03): a line item whose effective exclusion labels (union of advertiser, campaign order, and line item) intersect this set is ineligible here.\n"
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "warm_pool": {
      "$ref": "#/components/schemas/WarmPoolConfig"
    },
    "dual_mode": {
      "$ref": "#/components/schemas/DualModeConfig"
    },
    "stitch": {
      "$ref": "#/components/schemas/StitchConfig"
    },
    "demand_attachment": {
      "$ref": "#/components/schemas/DemandAttachmentConfig"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400,
      "description": "Supply-side delivery window override (seconds); precedence over publisher/tenant."
    },
    "line_item_ttl_minutes": {
      "type": "integer",
      "minimum": 5,
      "maximum": 1440,
      "description": "Direct line-item beacon validity (minutes); default 60 when unset."
    },
    "remainder_pct": {
      "type": "integer",
      "minimum": 0,
      "maximum": 99,
      "description": "CP-17 selection exploration percent (0–99). Omit/null = unset (no placement override).\n"
    },
    "auction_type": {
      "$ref": "#/components/schemas/DealAuctionType"
    },
    "companion_slots": {
      "type": "array",
      "maxItems": 8,
      "items": {
        "$ref": "#/components/schemas/CompanionSlotSpec"
      },
      "description": "Companion ad slots the placement's player can render (SR-1211): a creative's companions are matched to these by size; a `required` slot with no matching companion makes the creative ineligible here. Arrays present on update replace the full set.\n"
    },
    "live_stream": {
      "nullable": true,
      "description": "Live-stream insertion settings (SR-1211 / design 38). On update, omitted = unchanged and an explicit null clears them (the DemandPartner nullable-clears rule).",
      "allOf": [
        {
          "$ref": "#/components/schemas/LiveStreamConfig"
        }
      ]
    }
  }
}
PlacementUpdate

schemas/AdminPricingschemas/AdminCpmCapschemas/EntityVerificationschemas/WarmPoolConfigschemas/DualModeConfigschemas/StitchConfigschemas/DemandAttachmentConfigschemas/DealAuctionTypeschemas/CompanionSlotSpecschemas/LiveStreamConfig

{
  "type": "object",
  "description": "Partial update — omitted optional objects/fields leave stored values untouched (same convention as stitch and demand_attachment). Arrays present replace the full set.\n",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning publisher; must be an active publisher in the same tenant."
    },
    "media": {
      "type": "string",
      "enum": [
        "VIDEO",
        "AUDIO",
        "BANNER"
      ],
      "x-enum-varnames": [
        "PlacementUpdateMediaVIDEO",
        "PlacementUpdateMediaAUDIO",
        "PlacementUpdateMediaBANNER"
      ]
    },
    "floor": {
      "type": "string"
    },
    "pod_floor": {
      "type": "string"
    },
    "pricing": {
      "$ref": "#/components/schemas/AdminPricing"
    },
    "line_item_margin": {
      "type": "string"
    },
    "cpm_cap": {
      "$ref": "#/components/schemas/AdminCpmCap"
    },
    "upstream_cpm_cap": {
      "$ref": "#/components/schemas/AdminCpmCap"
    },
    "qps_limit": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "pod_enabled": {
      "type": "boolean"
    },
    "max_ad_duration": {
      "type": "integer",
      "minimum": 0
    },
    "max_pod_slots": {
      "type": "integer",
      "minimum": 0
    },
    "min_pod_duration": {
      "type": "integer",
      "minimum": 0
    },
    "max_pod_duration": {
      "type": "integer",
      "minimum": 0
    },
    "dedup_advertiser": {
      "type": "boolean"
    },
    "dedup_media": {
      "type": "boolean"
    },
    "dedup_category": {
      "type": "boolean"
    },
    "multi_imp": {
      "type": "boolean"
    },
    "packed_pixels": {
      "type": "boolean",
      "description": "Packed pixels (SR-1210 / SR-902, design 29 \"Rendering\"): true renders one platform beacon per event and the beacon fans the vendor tracker set out server-side from the sealed payload; false (default) renders every vendor URL into the document.\n"
    },
    "compliance_exempt": {
      "type": "boolean",
      "description": "Partner-approval gate exemption; see Placement.compliance_exempt."
    },
    "ignore_compliance": {
      "type": "boolean",
      "deprecated": true,
      "description": "Deprecated since Wave 8 round 2: alias of `compliance_exempt`, accepted and echoed for one release after CHANGELOG-api.md lists it; use `compliance_exempt`."
    },
    "blocked_advertisers": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "blocked_categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "allowed_advertisers": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 253
      },
      "description": "Advertiser allow-list for this placement (SR-1217; exact or parent-domain match). Non-empty overrides the publisher's allowed_advertisers; empty falls through to it.\n"
    },
    "vast_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /vast answers an empty VAST document (reason `vast_paused`) for this placement."
    },
    "ortb_serving_paused": {
      "type": "boolean",
      "description": "Kill switch (SR-1217): /ortb answers no-bid (reason `ortb_paused`) for this placement."
    },
    "blocked_exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels blocked on this placement (GC-03): a line item whose effective exclusion labels (union of advertiser, campaign order, and line item) intersect this set is ineligible here.\n"
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "warm_pool": {
      "$ref": "#/components/schemas/WarmPoolConfig"
    },
    "dual_mode": {
      "$ref": "#/components/schemas/DualModeConfig"
    },
    "stitch": {
      "$ref": "#/components/schemas/StitchConfig"
    },
    "demand_attachment": {
      "$ref": "#/components/schemas/DemandAttachmentConfig"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "delivery_window_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400,
      "description": "Supply-side delivery window override (seconds); precedence over publisher/tenant."
    },
    "line_item_ttl_minutes": {
      "type": "integer",
      "minimum": 5,
      "maximum": 1440,
      "description": "Direct line-item beacon validity (minutes); default 60 when unset."
    },
    "remainder_pct": {
      "type": "integer",
      "minimum": 0,
      "maximum": 99,
      "description": "CP-17 selection exploration percent (0–99). Omit to leave the stored value untouched (same partial-update convention as other optional scalars).\n"
    },
    "auction_type": {
      "$ref": "#/components/schemas/DealAuctionType"
    },
    "companion_slots": {
      "type": "array",
      "maxItems": 8,
      "items": {
        "$ref": "#/components/schemas/CompanionSlotSpec"
      },
      "description": "Companion ad slots the placement's player can render (SR-1211): a creative's companions are matched to these by size; a `required` slot with no matching companion makes the creative ineligible here. Arrays present on update replace the full set.\n"
    },
    "live_stream": {
      "nullable": true,
      "description": "Live-stream insertion settings (SR-1211 / design 38). On update, omitted = unchanged and an explicit null clears them (the DemandPartner nullable-clears rule).",
      "allOf": [
        {
          "$ref": "#/components/schemas/LiveStreamConfig"
        }
      ]
    }
  }
}
CompanionSlotSpec

{
  "type": "object",
  "description": "One companion ad slot a placement's player renders (SR-1211).",
  "required": [
    "width",
    "height"
  ],
  "properties": {
    "width": {
      "type": "integer",
      "minimum": 1,
      "description": "Slot width in pixels."
    },
    "height": {
      "type": "integer",
      "minimum": 1,
      "description": "Slot height in pixels."
    },
    "required": {
      "type": "boolean",
      "description": "True when a creative without a companion of this size is ineligible on the placement."
    }
  }
}
LiveStreamBreakSource

{
  "type": "string",
  "description": "How ad breaks are detected in a live HLS stream (SR-1211): CUE (EXT-X-CUE-OUT/IN tags), SCTE35 (EXT-X-DATERANGE SCTE-35 markers), PDT (EXT-X-PROGRAM-DATE-TIME schedule match), SCHEDULE (operator-defined break times).\n",
  "enum": [
    "CUE",
    "SCTE35",
    "PDT",
    "SCHEDULE"
  ],
  "x-enum-varnames": [
    "LiveStreamBreakSourceCUE",
    "LiveStreamBreakSourceSCTE35",
    "LiveStreamBreakSourcePDT",
    "LiveStreamBreakSourceSCHEDULE"
  ]
}
LiveStreamConfig

schemas/LiveStreamBreakSource

{
  "type": "object",
  "description": "Live-stream ad insertion for an HLS placement (SR-1211): the stitcher rewrites the origin's sliding-window manifest, fills breaks from the auction, and serves predicted segment URLs ahead of the break.\n",
  "properties": {
    "enabled": {
      "type": "boolean",
      "description": "True to serve this placement through live-stream insertion; false leaves the origin manifest untouched."
    },
    "window_segments": {
      "type": "integer",
      "minimum": 1,
      "maximum": 600,
      "description": "Number of media segments kept in the rewritten sliding window."
    },
    "break_source": {
      "$ref": "#/components/schemas/LiveStreamBreakSource"
    },
    "predicted_url_template": {
      "type": "string",
      "maxLength": 2048,
      "description": "URL template for predicted ad segments served before the break is filled ({{SESSION}} / {{SEQ}} macros)."
    },
    "aes_key_uri": {
      "type": "string",
      "maxLength": 2048,
      "description": "EXT-X-KEY URI the rewritten manifest advertises when the origin is AES-128 encrypted; omit for clear streams."
    }
  }
}
PlacementList

schemas/Placement

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Placement"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
SealingKeyStatus

{
  "type": "string",
  "enum": [
    "ACTIVE",
    "RETIRED"
  ],
  "x-enum-varnames": [
    "SealingKeyStatusACTIVE",
    "SealingKeyStatusRETIRED"
  ]
}
SealingKey

schemas/SealingKeyStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "key_id",
    "status",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Row id (internal)."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "key_id": {
      "type": "string",
      "description": "Opaque id embedded in sealed payloads; used in retire path."
    },
    "status": {
      "$ref": "#/components/schemas/SealingKeyStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "retired_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
SealingKeyCreate

{
  "type": "object",
  "properties": {
    "key_id": {
      "type": "string",
      "minLength": 1,
      "description": "Optional opaque key id; server generates when omitted."
    }
  }
}
SealingKeyList

schemas/SealingKey

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/SealingKey"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
DemandPartner

schemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "name",
    "adapter",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "adapter": {
      "type": "string"
    },
    "approvals_required": {
      "type": "boolean"
    },
    "timeout_ms": {
      "type": "integer",
      "minimum": 1
    },
    "max_concurrency": {
      "type": "integer",
      "nullable": true,
      "minimum": 1,
      "description": "Maximum concurrent outbound calls a serving node keeps in flight to this partner; omitted = unlimited."
    },
    "rev_share": {
      "type": "string"
    },
    "flat_cost": {
      "type": "string"
    },
    "sync_redirect": {
      "type": "string"
    },
    "tcf_vendor_id": {
      "type": "integer",
      "minimum": 1,
      "description": "IAB TCF vendor id for vendor-scoped GDPR forwards."
    },
    "bid_ttl_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400,
      "description": "Default buyer notice tolerance (seconds) when bid.exp is omitted."
    },
    "openrtb_version": {
      "type": "string",
      "enum": [
        "",
        "2.5",
        "2.6"
      ],
      "description": "OpenRTB version the partner speaks (SR-1207, design 06 \"Outbound request construction\"): empty = 2.6 (default). 2.5 downgrades the 2.6-only objects on the outbound request and parses the response as 2.5.\n"
    },
    "warm_pool_no_cache": {
      "type": "boolean",
      "description": "Opt every bid of this partner out of the warm pool (docs/design/17-warm-pool.md Eligibility)."
    },
    "warm_pool_allow_deals": {
      "type": "boolean",
      "description": "Allow this partner's deal/PMP bids to be cached in the warm pool (never cached otherwise)."
    },
    "warm_pool_ttl_class": {
      "type": "string",
      "enum": [
        "",
        "default",
        "short",
        "long",
        "buyer_exp"
      ],
      "description": "Warm-pool TTL class override for this partner; empty uses the placement class."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DemandPartnerCreate

{
  "type": "object",
  "required": [
    "name",
    "adapter"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "adapter": {
      "type": "string",
      "minLength": 1
    },
    "approvals_required": {
      "type": "boolean"
    },
    "timeout_ms": {
      "type": "integer",
      "minimum": 1
    },
    "max_concurrency": {
      "type": "integer",
      "nullable": true,
      "minimum": 1,
      "description": "Maximum concurrent outbound calls a serving node keeps in flight to this partner; omitted = unlimited."
    },
    "rev_share": {
      "type": "string"
    },
    "flat_cost": {
      "type": "string"
    },
    "sync_redirect": {
      "type": "string"
    },
    "tcf_vendor_id": {
      "type": "integer",
      "minimum": 1
    },
    "bid_ttl_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400
    },
    "openrtb_version": {
      "type": "string",
      "enum": [
        "",
        "2.5",
        "2.6"
      ],
      "description": "OpenRTB version the partner speaks (SR-1207, design 06 \"Outbound request construction\"): empty = 2.6 (default). 2.5 downgrades the 2.6-only objects on the outbound request and parses the response as 2.5.\n"
    },
    "warm_pool_no_cache": {
      "type": "boolean",
      "description": "Opt every bid of this partner out of the warm pool (docs/design/17-warm-pool.md Eligibility)."
    },
    "warm_pool_allow_deals": {
      "type": "boolean",
      "description": "Allow this partner's deal/PMP bids to be cached in the warm pool (never cached otherwise)."
    },
    "warm_pool_ttl_class": {
      "type": "string",
      "enum": [
        "",
        "default",
        "short",
        "long",
        "buyer_exp"
      ],
      "description": "Warm-pool TTL class override for this partner; empty uses the placement class."
    }
  }
}
DemandPartnerUpdate

{
  "type": "object",
  "description": "Partial update by presence. Optional integers (`timeout_ms`, `max_concurrency`, `tcf_vendor_id`) follow the nullable-clears rule (docs/spec/api-fundamentals.md \"Nullable fields\"): omitted leaves the stored value, an explicit `null` clears it back to unset.\n",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "approvals_required": {
      "type": "boolean"
    },
    "timeout_ms": {
      "type": "integer",
      "nullable": true,
      "minimum": 1,
      "description": "Partner timeout; omitted = unchanged, null = clear to the process default."
    },
    "max_concurrency": {
      "type": "integer",
      "nullable": true,
      "minimum": 1,
      "description": "Maximum concurrent outbound calls a serving node keeps in flight to this partner; omitted = unchanged, null = unlimited."
    },
    "rev_share": {
      "type": "string"
    },
    "flat_cost": {
      "type": "string"
    },
    "sync_redirect": {
      "type": "string"
    },
    "tcf_vendor_id": {
      "type": "integer",
      "nullable": true,
      "minimum": 1,
      "description": "IAB TCF vendor id; omitted = unchanged, null = clear (no vendor-scoped deny path)."
    },
    "bid_ttl_seconds": {
      "type": "integer",
      "minimum": 60,
      "maximum": 86400
    },
    "openrtb_version": {
      "type": "string",
      "enum": [
        "",
        "2.5",
        "2.6"
      ],
      "description": "OpenRTB version the partner speaks (SR-1207, design 06 \"Outbound request construction\"): empty = 2.6 (default). 2.5 downgrades the 2.6-only objects on the outbound request and parses the response as 2.5.\n"
    },
    "warm_pool_no_cache": {
      "type": "boolean",
      "description": "Opt every bid of this partner out of the warm pool (docs/design/17-warm-pool.md Eligibility)."
    },
    "warm_pool_allow_deals": {
      "type": "boolean",
      "description": "Allow this partner's deal/PMP bids to be cached in the warm pool (never cached otherwise)."
    },
    "warm_pool_ttl_class": {
      "type": "string",
      "enum": [
        "",
        "default",
        "short",
        "long",
        "buyer_exp"
      ],
      "description": "Warm-pool TTL class override for this partner; empty uses the placement class."
    }
  }
}
DemandPartnerList

schemas/DemandPartner

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DemandPartner"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
App

schemas/AppPricingEntryschemas/RouteApprovalEntryschemas/LifecycleStatus

{
  "type": "object",
  "description": "App inventory — docs/design/02-data-model.md \"Supply\". Includes publisher_pricing and route_approvals maps (RIP-133).\n",
  "required": [
    "id",
    "tenant_id",
    "name",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "bundle_id": {
      "type": "string"
    },
    "store_id": {
      "type": "string"
    },
    "domain": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "platform_id": {
      "type": "string",
      "format": "uuid",
      "description": "Global device/CTV platform catalog reference."
    },
    "language": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "store_urls": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "max_ad_duration": {
      "type": "integer",
      "minimum": 0
    },
    "publisher_pricing": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/AppPricingEntry"
      },
      "description": "Keyed by publisher id."
    },
    "route_approvals": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/RouteApprovalEntry"
      },
      "description": "Keyed by demand partner id."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
AppCreate

schemas/AppPricingEntryschemas/RouteApprovalEntry

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "bundle_id": {
      "type": "string"
    },
    "store_id": {
      "type": "string"
    },
    "domain": {
      "type": "string"
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "platform_id": {
      "type": "string",
      "format": "uuid"
    },
    "language": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "store_urls": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "max_ad_duration": {
      "type": "integer",
      "minimum": 0
    },
    "publisher_pricing": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/AppPricingEntry"
      }
    },
    "route_approvals": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/RouteApprovalEntry"
      }
    }
  }
}
AppUpdate

schemas/AppPricingEntryschemas/RouteApprovalEntry

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "domain": {
      "type": "string"
    },
    "language": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "store_urls": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "max_ad_duration": {
      "type": "integer",
      "minimum": 0
    },
    "publisher_pricing": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/AppPricingEntry"
      }
    },
    "route_approvals": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/RouteApprovalEntry"
      }
    }
  }
}
AppList

schemas/App

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/App"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
DemandRouteIntegration

{
  "type": "string",
  "description": "Demand route integration kind (riptide.common.v1.IntegrationKind).",
  "enum": [
    "ORTB",
    "VAST",
    "ADAPTER",
    "CUSTOM"
  ],
  "x-enum-varnames": [
    "DemandRouteIntegrationORTB",
    "DemandRouteIntegrationVAST",
    "DemandRouteIntegrationADAPTER",
    "DemandRouteIntegrationCUSTOM"
  ]
}
DemandRoute

schemas/DemandRouteIntegrationschemas/FanoutConfigschemas/SupplyTransparencyPolicyschemas/LifecycleStatus

{
  "type": "object",
  "description": "A configured path to a partner's demand — docs/design/06-demand.md. Includes endpoints, seats, deals, params, fanout, and audience binding (RIP-133 settings flexibility). Request rewrites remain a dedicated sub-resource.\n",
  "required": [
    "id",
    "tenant_id",
    "demand_partner_id",
    "integration",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "demand_partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "integration": {
      "$ref": "#/components/schemas/DemandRouteIntegration"
    },
    "name": {
      "type": "string",
      "maxLength": 200,
      "description": "Operator-facing route name shown in lists and pickers (REM-J); the id stays the key."
    },
    "media": {
      "type": "string",
      "enum": [
        "VIDEO",
        "AUDIO",
        "BANNER"
      ]
    },
    "endpoints": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Region → bid endpoint URI map."
    },
    "target_cpm": {
      "type": "string",
      "description": "When set, bids on this route skip the partner revenue-share deflation (the flat cost still applies) — docs/design/08-economics.md \"Bid pre-process\"."
    },
    "floor": {
      "type": "string",
      "description": "Route floor (decimal CPM): REPLACES the placement floor as the base of the floor sent to this partner; the request floor only raises it."
    },
    "flat_cost": {
      "type": "string",
      "description": "Route-level IO/flat cost (decimal CPM) subtracted from every bid after the revenue-share deflation; overrides the partner's flat_cost."
    },
    "qps": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "integer",
      "minimum": 0
    },
    "gzip": {
      "type": "boolean"
    },
    "require_advertiser": {
      "type": "boolean"
    },
    "require_category": {
      "type": "boolean"
    },
    "supply_chain_asi": {
      "type": "string"
    },
    "seller_id": {
      "type": "string"
    },
    "private_auction": {
      "type": "boolean"
    },
    "params": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Adapter macros / partner params."
    },
    "fanout": {
      "$ref": "#/components/schemas/FanoutConfig"
    },
    "seats": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "deals": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Deal ids bound to this route."
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "marketplace_id": {
      "type": "string",
      "format": "uuid"
    },
    "marketplace_rev_share": {
      "type": "string"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "unwrap_depth": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10,
      "description": "<Wrapper> hops the hub follows for this route's VAST bids before serving the bid as is (SR-1210, design 10 \"Demand bid unwrap\"); omitted = the process default, 0 = never unwrap.\n"
    },
    "fixed_cpm": {
      "type": "string",
      "description": "Fixed CPM (decimal, 4 dp) a VAST-tag route (integration VAST) bids when the partner's tag carries no <Pricing> (SR-1235, design 06 \"Adapters\"); omitted = such a tag is a no-bid.\n"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DemandRouteCreate

schemas/DemandRouteIntegrationschemas/FanoutConfigschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "required": [
    "demand_partner_id",
    "integration"
  ],
  "properties": {
    "demand_partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "integration": {
      "$ref": "#/components/schemas/DemandRouteIntegration"
    },
    "name": {
      "type": "string",
      "maxLength": 200,
      "description": "Operator-facing route name; see DemandRoute.name."
    },
    "media": {
      "type": "string",
      "enum": [
        "VIDEO",
        "AUDIO",
        "BANNER"
      ]
    },
    "endpoints": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "target_cpm": {
      "type": "string",
      "description": "When set, bids on this route skip the partner revenue-share deflation (the flat cost still applies) — docs/design/08-economics.md \"Bid pre-process\"."
    },
    "floor": {
      "type": "string",
      "description": "Route floor (decimal CPM): REPLACES the placement floor as the base of the floor sent to this partner; the request floor only raises it."
    },
    "flat_cost": {
      "type": "string",
      "description": "Route-level IO/flat cost (decimal CPM) subtracted from every bid after the revenue-share deflation; overrides the partner's flat_cost."
    },
    "qps": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "integer",
      "minimum": 0
    },
    "gzip": {
      "type": "boolean"
    },
    "require_advertiser": {
      "type": "boolean"
    },
    "require_category": {
      "type": "boolean"
    },
    "supply_chain_asi": {
      "type": "string"
    },
    "seller_id": {
      "type": "string"
    },
    "private_auction": {
      "type": "boolean"
    },
    "params": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "fanout": {
      "$ref": "#/components/schemas/FanoutConfig"
    },
    "seats": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "deals": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "marketplace_id": {
      "type": "string",
      "format": "uuid"
    },
    "marketplace_rev_share": {
      "type": "string"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "unwrap_depth": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10,
      "description": "<Wrapper> hops the hub follows for this route's VAST bids before serving the bid as is (SR-1210, design 10 \"Demand bid unwrap\"); omitted = the process default, 0 = never unwrap.\n"
    },
    "fixed_cpm": {
      "type": "string",
      "description": "Fixed CPM (decimal, 4 dp) a VAST-tag route (integration VAST) bids when the partner's tag carries no <Pricing> (SR-1235, design 06 \"Adapters\"); omitted = such a tag is a no-bid.\n"
    }
  }
}
DemandRouteUpdate

schemas/FanoutConfigschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "properties": {
    "media": {
      "type": "string",
      "enum": [
        "VIDEO",
        "AUDIO",
        "BANNER"
      ]
    },
    "name": {
      "type": "string",
      "maxLength": 200,
      "description": "Operator-facing route name; see DemandRoute.name. Omitted = unchanged."
    },
    "endpoints": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "target_cpm": {
      "type": "string",
      "description": "When set, bids on this route skip the partner revenue-share deflation (the flat cost still applies) — docs/design/08-economics.md \"Bid pre-process\"."
    },
    "floor": {
      "type": "string",
      "description": "Route floor (decimal CPM): REPLACES the placement floor as the base of the floor sent to this partner; the request floor only raises it."
    },
    "flat_cost": {
      "type": "string",
      "description": "Route-level IO/flat cost (decimal CPM) subtracted from every bid after the revenue-share deflation; overrides the partner's flat_cost."
    },
    "qps": {
      "type": "integer",
      "minimum": 0
    },
    "share_of_voice": {
      "type": "integer",
      "minimum": 0
    },
    "gzip": {
      "type": "boolean"
    },
    "require_advertiser": {
      "type": "boolean"
    },
    "require_category": {
      "type": "boolean"
    },
    "supply_chain_asi": {
      "type": "string"
    },
    "seller_id": {
      "type": "string"
    },
    "private_auction": {
      "type": "boolean"
    },
    "params": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "fanout": {
      "$ref": "#/components/schemas/FanoutConfig"
    },
    "seats": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "deals": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "marketplace_id": {
      "type": "string",
      "format": "uuid"
    },
    "marketplace_rev_share": {
      "type": "string"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "unwrap_depth": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10,
      "description": "<Wrapper> hops the hub follows for this route's VAST bids before serving the bid as is (SR-1210, design 10 \"Demand bid unwrap\"); omitted = the process default, 0 = never unwrap.\n"
    },
    "fixed_cpm": {
      "type": "string",
      "description": "Fixed CPM (decimal, 4 dp) a VAST-tag route (integration VAST) bids when the partner's tag carries no <Pricing> (SR-1235, design 06 \"Adapters\"); omitted = such a tag is a no-bid.\n"
    }
  }
}
DemandRouteList

schemas/DemandRoute

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DemandRoute"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
RouteRewrite

{
  "type": "object",
  "description": "A single request-rewrite rule on a demand route (route_rewrite, docs/design/06-demand.md) — P3-03's admin surface for the table 0002_demand always carried. Exactly one of `value` (when overwriting/appending a field) or `clear` (removing it) applies; a rule cannot be both.\n",
  "required": [
    "id",
    "path"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "path": {
      "type": "string",
      "minLength": 1,
      "description": "The bid-request field path to rewrite."
    },
    "value": {
      "type": "string",
      "description": "Replacement value; empty when clear is true."
    },
    "overwrite": {
      "type": "boolean",
      "description": "Replace an existing value rather than only filling an empty one."
    },
    "clear": {
      "type": "boolean",
      "description": "Remove the field instead of setting a value."
    }
  }
}
RouteRewriteCreate

{
  "type": "object",
  "required": [
    "path"
  ],
  "properties": {
    "path": {
      "type": "string",
      "minLength": 1
    },
    "value": {
      "type": "string"
    },
    "overwrite": {
      "type": "boolean"
    },
    "clear": {
      "type": "boolean"
    }
  }
}
RouteRewriteSet

schemas/RouteRewriteCreate

{
  "type": "object",
  "required": [
    "rewrites"
  ],
  "properties": {
    "rewrites": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/RouteRewriteCreate"
      }
    }
  }
}
RouteRewriteList

schemas/RouteRewrite

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/RouteRewrite"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
DemandRouteRewritePreviewRequest

{
  "type": "object",
  "required": [
    "bid_request"
  ],
  "description": "Sample OpenRTB bid request to run through the route's saved rewrite rules. The request must contain exactly one imp, matching Riptide's current one-opportunity-per-request outbound builder.\n",
  "properties": {
    "bid_request": {
      "type": "object",
      "additionalProperties": true
    }
  }
}
DemandRouteRewritePreviewResponse

schemas/RouteRewrite

{
  "type": "object",
  "required": [
    "original_bid_request",
    "rewritten_bid_request",
    "applied_rewrites"
  ],
  "properties": {
    "original_bid_request": {
      "type": "object",
      "additionalProperties": true
    },
    "rewritten_bid_request": {
      "type": "object",
      "additionalProperties": true
    },
    "applied_rewrites": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/RouteRewrite"
      }
    }
  }
}
DealAuctionType

{
  "type": "string",
  "description": "riptide.common.v1.AuctionType.",
  "enum": [
    "FIRST_PRICE",
    "SECOND_PRICE",
    "BID_FLOOR"
  ]
}
DealKind

{
  "type": "string",
  "description": "Negotiated access kind. Omit on create/update to inherit from guaranteed (true -> GUARANTEED, false -> PREFERRED).\n",
  "enum": [
    "PREFERRED",
    "GUARANTEED",
    "PRIVATE"
  ]
}
Deal

schemas/DealAuctionTypeschemas/DealKindschemas/EntityVerificationschemas/FrequencyCapschemas/SupplyTransparencyPolicyschemas/LifecycleStatus

{
  "type": "object",
  "description": "A negotiated buy — docs/design/06-demand.md. Full surface includes seats, advertiser domains, kind, flight, verification, audience, and per-deal frequency caps (RIP-133).\n",
  "required": [
    "id",
    "tenant_id",
    "external_id",
    "name",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "external_id": {
      "type": "string",
      "description": "The negotiated deal id sent to demand."
    },
    "name": {
      "type": "string"
    },
    "auction_type": {
      "$ref": "#/components/schemas/DealAuctionType"
    },
    "floor": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "guaranteed": {
      "type": "boolean",
      "description": "Wins outright when matched."
    },
    "kind": {
      "$ref": "#/components/schemas/DealKind"
    },
    "flight_start": {
      "type": "string",
      "format": "date-time",
      "description": "Inclusive UTC flight start."
    },
    "flight_end": {
      "type": "string",
      "format": "date-time",
      "description": "Exclusive UTC flight end; omit for open-ended."
    },
    "priority": {
      "type": "integer",
      "format": "int32",
      "default": 0,
      "description": "Preferred ranking hint; higher first."
    },
    "committed_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Volume commitment in impressions (GC-06, RIPTIDE-87, ADR D54 D-02). Exactly one of committed_impressions / committed_spend may be set; a commitment requires guaranteed=true AND a bounded flight (flight_end set). The commitment paces the deal's guaranteed outright wins; under-delivery surfaces as a makegood recommendation, never a credit. Omit both for no commitment (today's behavior).\n"
    },
    "committed_spend": {
      "type": "string",
      "description": "Volume commitment as spend — decimal money string (4dp), e.g. \"5000.0000\", in the deal's currency (GC-06, RIPTIDE-87, ADR D54 D-02). Exactly one of committed_impressions / committed_spend may be set; a commitment requires guaranteed=true AND a bounded flight (flight_end set). The commitment paces the deal's guaranteed outright wins; under-delivery surfaces as a makegood recommendation, never a credit. Omit both for no commitment (today's behavior).\n"
    },
    "format": {
      "type": "string"
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid"
    },
    "seats": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "advertiser_domains": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "first_impression": {
      "type": "boolean"
    },
    "all_pods": {
      "type": "boolean"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCap"
      }
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DealMakegoodRecommendation

{
  "type": "object",
  "description": "libs/auction/direct.RecommendMakegood's answer for one committed guaranteed deal (design 31 \"Pacing parity\" deal commitments; ADR D54 D-02): the commitment in its primary unit, what the deal-scoped counters delivered, the shortfall, the delivery percent against the linear pace, and the status. counters_available=false means the hot store is not configured (or unreachable) and delivered reads zero — reported honestly, never guessed.\n",
  "required": [
    "deal_id",
    "external_id",
    "unit",
    "committed",
    "delivered",
    "shortfall",
    "delivery_pct",
    "expected_pct",
    "status",
    "recommend",
    "counters_available",
    "computed_at"
  ],
  "properties": {
    "deal_id": {
      "type": "string",
      "format": "uuid"
    },
    "external_id": {
      "type": "string",
      "description": "The negotiated deal id sent to demand."
    },
    "unit": {
      "type": "string",
      "enum": [
        "impressions",
        "spend"
      ],
      "x-enum-varnames": [
        "DealMakegoodUnitImpressions",
        "DealMakegoodUnitSpend"
      ],
      "description": "The commitment's primary unit: impressions (committed_impressions) or spend (committed_spend). committed / delivered / shortfall are counts for impressions and integer micros of the deal currency for spend — the counters' own unit.\n"
    },
    "committed": {
      "type": "integer",
      "format": "int64"
    },
    "delivered": {
      "type": "integer",
      "format": "int64"
    },
    "shortfall": {
      "type": "integer",
      "format": "int64",
      "description": "committed − delivered when positive; 0 once delivered."
    },
    "delivery_pct": {
      "type": "number",
      "format": "double",
      "description": "delivered ÷ committed × 100 (not clamped, so over-delivery shows)."
    },
    "expected_pct": {
      "type": "number",
      "format": "double",
      "description": "The linear pace by now over the flight: 0 before the start, 100 at/after the end, proportional in between; equal to delivery_pct when the flight is unbounded (an open-ended deal is never behind).\n"
    },
    "status": {
      "type": "string",
      "enum": [
        "on_track",
        "behind",
        "delivered",
        "shortfall"
      ],
      "x-enum-varnames": [
        "DealMakegoodStatusOnTrack",
        "DealMakegoodStatusBehind",
        "DealMakegoodStatusDelivered",
        "DealMakegoodStatusShortfall"
      ],
      "description": "on_track = delivery within 10 percentage points of the linear pace; behind = in flight and more than 10 points under pace; delivered = commitment met (100 % or more); shortfall = the flight ended under 100 % — a makegood is recommended.\n"
    },
    "recommend": {
      "type": "boolean",
      "description": "True only for shortfall: offer a makegood (extension or bonus inventory)."
    },
    "flight_end": {
      "type": "string",
      "format": "date-time",
      "description": "Exclusive UTC flight end; absent for an open-ended deal."
    },
    "counters_available": {
      "type": "boolean"
    },
    "computed_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DealCreate

schemas/DealAuctionTypeschemas/DealKindschemas/EntityVerificationschemas/FrequencyCapInputschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "required": [
    "external_id",
    "name"
  ],
  "properties": {
    "external_id": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "auction_type": {
      "$ref": "#/components/schemas/DealAuctionType"
    },
    "floor": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "guaranteed": {
      "type": "boolean"
    },
    "kind": {
      "$ref": "#/components/schemas/DealKind"
    },
    "flight_start": {
      "type": "string",
      "format": "date-time"
    },
    "flight_end": {
      "type": "string",
      "format": "date-time"
    },
    "priority": {
      "type": "integer",
      "format": "int32",
      "default": 0
    },
    "committed_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Volume commitment in impressions (GC-06, RIPTIDE-87, ADR D54 D-02). Exactly one of committed_impressions / committed_spend may be set (both set is rejected); a commitment requires guaranteed=true AND a bounded flight (flight_end set). The commitment paces the deal's guaranteed outright wins; under-delivery surfaces as a makegood recommendation, never a credit. Omit both for no commitment (today's behavior).\n"
    },
    "committed_spend": {
      "type": "string",
      "description": "Volume commitment as spend — decimal money string (4dp), e.g. \"5000.0000\", in the deal's currency (GC-06, RIPTIDE-87, ADR D54 D-02). Exactly one of committed_impressions / committed_spend may be set (both set is rejected); a commitment requires guaranteed=true AND a bounded flight (flight_end set). The commitment paces the deal's guaranteed outright wins; under-delivery surfaces as a makegood recommendation, never a credit. Omit both for no commitment (today's behavior).\n"
    },
    "format": {
      "type": "string"
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid"
    },
    "seats": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "advertiser_domains": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "first_impression": {
      "type": "boolean"
    },
    "all_pods": {
      "type": "boolean"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCapInput"
      }
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    }
  }
}
DealUpdate

schemas/DealAuctionTypeschemas/DealKindschemas/EntityVerificationschemas/FrequencyCapInputschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "auction_type": {
      "$ref": "#/components/schemas/DealAuctionType"
    },
    "floor": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "guaranteed": {
      "type": "boolean"
    },
    "kind": {
      "$ref": "#/components/schemas/DealKind"
    },
    "flight_start": {
      "type": "string",
      "format": "date-time"
    },
    "flight_end": {
      "type": "string",
      "format": "date-time"
    },
    "priority": {
      "type": "integer",
      "format": "int32",
      "default": 0
    },
    "committed_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Volume commitment in impressions (GC-06, RIPTIDE-87, ADR D54 D-02). Exactly one of committed_impressions / committed_spend may be set (both set is rejected); a commitment requires guaranteed=true AND a bounded flight (flight_end set). The commitment paces the deal's guaranteed outright wins; under-delivery surfaces as a makegood recommendation, never a credit. Omit both to clear the commitment (today's behavior).\n"
    },
    "committed_spend": {
      "type": "string",
      "description": "Volume commitment as spend — decimal money string (4dp), e.g. \"5000.0000\", in the deal's currency (GC-06, RIPTIDE-87, ADR D54 D-02). Exactly one of committed_impressions / committed_spend may be set (both set is rejected); a commitment requires guaranteed=true AND a bounded flight (flight_end set). The commitment paces the deal's guaranteed outright wins; under-delivery surfaces as a makegood recommendation, never a credit. Omit both to clear the commitment (today's behavior).\n"
    },
    "format": {
      "type": "string"
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid"
    },
    "seats": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "advertiser_domains": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "first_impression": {
      "type": "boolean"
    },
    "all_pods": {
      "type": "boolean"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCapInput"
      }
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    }
  }
}
DealList

schemas/Deal

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Deal"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
Marketplace

schemas/LifecycleStatus

{
  "type": "object",
  "description": "A packaged bundle of demand routes attached to supply — docs/design/06-demand.md. Placement membership is managed separately via PUT .../placements/{placement_id}/marketplaces.\n",
  "required": [
    "id",
    "tenant_id",
    "code",
    "name",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "code": {
      "type": "integer",
      "description": "Stable int identity exposed to the runtime plan proto."
    },
    "name": {
      "type": "string"
    },
    "rev_share": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
MarketplaceCreate

{
  "type": "object",
  "required": [
    "code",
    "name"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "rev_share": {
      "type": "string"
    }
  }
}
MarketplaceUpdate

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "rev_share": {
      "type": "string"
    }
  }
}
MarketplaceList

schemas/Marketplace

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Marketplace"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
MarketplaceDealMembership

{
  "type": "object",
  "required": [
    "deal_ids"
  ],
  "properties": {
    "deal_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Opaque cursor for the next page of ids; absent on the last page."
    }
  }
}
ListingVisibility

{
  "type": "string",
  "description": "Discovery scope for a MarketplaceListing (design 24 §4.1).",
  "enum": [
    "PRIVATE",
    "TENANT",
    "FEDERATED"
  ],
  "x-enum-varnames": [
    "ListingVisibilityPRIVATE",
    "ListingVisibilityTENANT",
    "ListingVisibilityFEDERATED"
  ]
}
ListingStatus

{
  "type": "string",
  "description": "Lifecycle status for a MarketplaceListing.",
  "enum": [
    "DRAFT",
    "PUBLISHED",
    "PAUSED",
    "ARCHIVED"
  ],
  "x-enum-varnames": [
    "ListingStatusDRAFT",
    "ListingStatusPUBLISHED",
    "ListingStatusPAUSED",
    "ListingStatusARCHIVED"
  ]
}
ListingKind

{
  "type": "string",
  "description": "Commercial role of a MarketplaceListing (design 25 §5). UNSPECIFIED treated as SUPPLY_PACK.",
  "enum": [
    "UNSPECIFIED",
    "SUPPLY_PACK",
    "DEMAND_CAPACITY",
    "BUYER_PACK",
    "STACK_PRODUCT"
  ],
  "x-enum-varnames": [
    "ListingKindUNSPECIFIED",
    "ListingKindSUPPLYPACK",
    "ListingKindDEMANDCAPACITY",
    "ListingKindBUYERPACK",
    "ListingKindSTACKPRODUCT"
  ]
}
ListingPaymentProfile

{
  "type": "string",
  "description": "Payment obligation for activating a listing (design 25). Default NET_30.",
  "enum": [
    "UNSPECIFIED",
    "PREPAY",
    "NET_30",
    "ESCROW_HOSTED"
  ],
  "x-enum-varnames": [
    "ListingPaymentProfileUNSPECIFIED",
    "ListingPaymentProfilePREPAY",
    "ListingPaymentProfileNET30",
    "ListingPaymentProfileESCROWHOSTED"
  ]
}
ListingTermsSummary

schemas/ListingKindschemas/ListingPaymentProfile

{
  "type": "object",
  "description": "Cached discovery DTO computed at publish (design 24 §5.2).",
  "required": [
    "listing_id",
    "code",
    "name"
  ],
  "properties": {
    "listing_id": {
      "type": "string",
      "format": "uuid"
    },
    "code": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "deal_kind_set": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "floor_cpm": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "flight_start_unix": {
      "type": "integer",
      "format": "int64"
    },
    "flight_end_unix": {
      "type": "integer",
      "format": "int64"
    },
    "media_types": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "formats": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "max_hops": {
      "type": "integer",
      "format": "int32"
    },
    "allow_reseller": {
      "type": "boolean"
    },
    "private_auction_required": {
      "type": "boolean"
    },
    "seat_restricted": {
      "type": "boolean"
    },
    "domain_restricted": {
      "type": "boolean"
    },
    "marketplace_code": {
      "type": "string"
    },
    "deal_count": {
      "type": "integer",
      "format": "int32"
    },
    "kind": {
      "$ref": "#/components/schemas/ListingKind"
    },
    "payment_profile": {
      "$ref": "#/components/schemas/ListingPaymentProfile"
    },
    "min_prepay": {
      "type": "string",
      "description": "Decimal string; PREPAY listings only."
    },
    "tenant_restricted": {
      "type": "boolean",
      "description": "True when buyer_tenant_allowlist is non-empty."
    }
  }
}
MarketplaceListing

schemas/ListingVisibilityschemas/ListingStatusschemas/ListingKindschemas/ListingPaymentProfileschemas/ListingTermsSummaryschemas/StackProductPublic

{
  "type": "object",
  "description": "Publishable commercial package for buyer discovery/activation (design 24 §4.1, design 25 §5). Does not replace Marketplace or Deal.\n",
  "required": [
    "id",
    "tenant_id",
    "code",
    "name",
    "visibility",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "code": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "visibility": {
      "$ref": "#/components/schemas/ListingVisibility"
    },
    "status": {
      "$ref": "#/components/schemas/ListingStatus"
    },
    "kind": {
      "$ref": "#/components/schemas/ListingKind"
    },
    "marketplace_id": {
      "type": "string",
      "format": "uuid"
    },
    "placement_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "deal_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "media_types": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "floor_cpm": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "flight_start_unix": {
      "type": "integer",
      "format": "int64"
    },
    "flight_end_unix": {
      "type": "integer",
      "format": "int64"
    },
    "max_hops": {
      "type": "integer",
      "format": "int32"
    },
    "allow_reseller": {
      "type": "boolean"
    },
    "buyer_seat_allowlist": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "buyer_tenant_allowlist": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "require_proposal": {
      "type": "boolean"
    },
    "payment_profile": {
      "$ref": "#/components/schemas/ListingPaymentProfile"
    },
    "terms_summary": {
      "$ref": "#/components/schemas/ListingTermsSummary"
    },
    "published_at": {
      "type": "string",
      "format": "date-time"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    },
    "stack_product": {
      "$ref": "#/components/schemas/StackProductPublic"
    }
  }
}
StackProductPublic

{
  "type": "object",
  "description": "Public stack-product catalog metadata (design 25 §8.1). Never includes capability tokens or resolved endpoints.",
  "properties": {
    "extension_kinds": {
      "type": "array",
      "description": "Kinds the product delivers. REPORT_FIELD and DECISIONER were retired by ADR D57 (their proto values are reserved); a write naming either is rejected with BAD_INPUT. They stay in the enum for one compatibility release so existing clients keep validating, then leave it.\n",
      "items": {
        "type": "string",
        "enum": [
          "BID_SOURCE",
          "DEMAND_ADAPTER",
          "ENRICHER",
          "AUDIENCE_EVALUATOR",
          "PRICING_MODULE",
          "CREATIVE_RENDERER",
          "VERIFICATION_VENDOR",
          "REPORT_FIELD",
          "DECISIONER",
          "DEMAND_ATTACHMENT"
        ]
      }
    },
    "distribution": {
      "type": "string",
      "enum": [
        "SIDECAR_ENDPOINT"
      ]
    },
    "endpoint_ref": {
      "type": "string"
    },
    "config_schema": {
      "type": "string"
    },
    "latency_budget_ms": {
      "type": "integer",
      "format": "int32"
    },
    "entitlement_key": {
      "type": "string"
    },
    "conformance_run_id": {
      "type": "string",
      "format": "uuid"
    },
    "trust_tier_required": {
      "type": "string",
      "enum": [
        "LIST",
        "ATTACH",
        "AUTONOMOUS_AGENT"
      ]
    },
    "pricing": {
      "type": "object",
      "properties": {
        "model": {
          "type": "string",
          "enum": [
            "FLAT_MONTHLY",
            "PER_INVOKE",
            "PER_ASSISTED_FILL",
            "REVSHARE_ASSISTED_SPEND"
          ]
        },
        "value": {
          "type": "string"
        },
        "currency": {
          "type": "string"
        }
      }
    }
  }
}
TenantExtension

{
  "type": "object",
  "description": "Installed stack-product ExtensionService projection (design 25 §8.3 / OM-22). Control-plane read model for bidding-agent UX — no capability tokens or dial secrets.\n",
  "required": [
    "id",
    "tenant_id",
    "activation_id",
    "product_listing_id",
    "extension_kind",
    "latency_budget_ms",
    "entitlement_key",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "activation_id": {
      "type": "string",
      "format": "uuid"
    },
    "product_listing_id": {
      "type": "string",
      "format": "uuid"
    },
    "product_listing_code": {
      "type": "string",
      "description": "Seller listing code when joinable; empty when listing archived."
    },
    "product_listing_name": {
      "type": "string",
      "description": "Seller listing name when joinable; empty when listing archived."
    },
    "extension_kind": {
      "type": "string",
      "description": "REPORT_FIELD and DECISIONER are retired (ADR D57): rejected on write with BAD_INPUT, kept in the enum for one compatibility release.\n",
      "enum": [
        "BID_SOURCE",
        "DEMAND_ADAPTER",
        "ENRICHER",
        "AUDIENCE_EVALUATOR",
        "PRICING_MODULE",
        "CREATIVE_RENDERER",
        "VERIFICATION_VENDOR",
        "REPORT_FIELD",
        "DECISIONER",
        "DEMAND_ATTACHMENT"
      ]
    },
    "latency_budget_ms": {
      "type": "integer",
      "format": "int32"
    },
    "entitlement_key": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
TenantExtensionList

schemas/TenantExtension

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/TenantExtension"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
StackProductInstallRequest

{
  "type": "object",
  "required": [
    "listing_id"
  ],
  "properties": {
    "listing_id": {
      "type": "string",
      "format": "uuid"
    },
    "config_json": {
      "type": "string",
      "description": "Validated install config JSON object."
    }
  }
}
RunExtensionConformanceRequest

{
  "type": "object",
  "required": [
    "vendor_tenant_id",
    "extension_kind",
    "harness_version"
  ],
  "properties": {
    "vendor_tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "extension_kind": {
      "type": "string"
    },
    "harness_version": {
      "type": "string"
    },
    "artifact_uri": {
      "type": "string"
    }
  }
}
ExtensionConformanceRunResult

{
  "type": "object",
  "required": [
    "conformance_run_id",
    "result",
    "operator_verified"
  ],
  "properties": {
    "conformance_run_id": {
      "type": "string",
      "format": "uuid"
    },
    "result": {
      "type": "string",
      "enum": [
        "PASS",
        "FAIL"
      ]
    },
    "operator_verified": {
      "type": "boolean"
    }
  }
}
MarketplaceListingCreate

schemas/ListingVisibilityschemas/ListingKindschemas/ListingPaymentProfile

{
  "type": "object",
  "required": [
    "code",
    "name",
    "visibility"
  ],
  "properties": {
    "code": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "visibility": {
      "$ref": "#/components/schemas/ListingVisibility"
    },
    "kind": {
      "$ref": "#/components/schemas/ListingKind"
    },
    "marketplace_id": {
      "type": "string",
      "format": "uuid"
    },
    "placement_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "deal_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "media_types": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "floor_cpm": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "flight_start_unix": {
      "type": "integer",
      "format": "int64"
    },
    "flight_end_unix": {
      "type": "integer",
      "format": "int64"
    },
    "max_hops": {
      "type": "integer",
      "format": "int32"
    },
    "allow_reseller": {
      "type": "boolean"
    },
    "buyer_seat_allowlist": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "buyer_tenant_allowlist": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "require_proposal": {
      "type": "boolean"
    },
    "payment_profile": {
      "$ref": "#/components/schemas/ListingPaymentProfile"
    }
  }
}
MarketplaceListingUpdate

schemas/ListingVisibilityschemas/ListingKindschemas/ListingPaymentProfile

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "visibility": {
      "$ref": "#/components/schemas/ListingVisibility"
    },
    "kind": {
      "$ref": "#/components/schemas/ListingKind"
    },
    "marketplace_id": {
      "type": "string",
      "format": "uuid"
    },
    "placement_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "deal_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "media_types": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "floor_cpm": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "flight_start_unix": {
      "type": "integer",
      "format": "int64"
    },
    "flight_end_unix": {
      "type": "integer",
      "format": "int64"
    },
    "max_hops": {
      "type": "integer",
      "format": "int32"
    },
    "allow_reseller": {
      "type": "boolean"
    },
    "buyer_seat_allowlist": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "buyer_tenant_allowlist": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "require_proposal": {
      "type": "boolean"
    },
    "payment_profile": {
      "$ref": "#/components/schemas/ListingPaymentProfile"
    }
  }
}
MarketplaceListingList

schemas/MarketplaceListing

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/MarketplaceListing"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ListingActivationEffect

{
  "type": "string",
  "enum": [
    "MERGE_DEALS_ONTO_ROUTE",
    "OPEN_DEMAND_EDGE",
    "ATTACH_TO_BUYER_PACK",
    "INSTALL_STACK_PRODUCT"
  ]
}
ListingActivationStatus

{
  "type": "string",
  "enum": [
    "ACTIVE",
    "PAUSED",
    "REVOKED"
  ],
  "x-enum-varnames": [
    "ListingActivationStatusACTIVE",
    "ListingActivationStatusPAUSED",
    "ListingActivationStatusREVOKED"
  ]
}
ListingActivation

schemas/ListingActivationEffectschemas/ListingActivationStatus

{
  "type": "object",
  "required": [
    "id",
    "activator_tenant_id",
    "owner_tenant_id",
    "listing_id",
    "effect",
    "status",
    "idempotency_key"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "activator_tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "owner_tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "listing_id": {
      "type": "string",
      "format": "uuid"
    },
    "effect": {
      "$ref": "#/components/schemas/ListingActivationEffect"
    },
    "demand_route_id": {
      "type": "string",
      "format": "uuid"
    },
    "demand_partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "buyer_seat": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/ListingActivationStatus"
    },
    "actor_label": {
      "type": "string"
    },
    "idempotency_key": {
      "type": "string"
    },
    "activated_at": {
      "type": "string",
      "format": "date-time"
    },
    "revoked_at": {
      "type": "string",
      "format": "date-time"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ListingActivationCreate

schemas/ListingActivationEffect

{
  "type": "object",
  "required": [
    "listing_id"
  ],
  "properties": {
    "listing_id": {
      "type": "string",
      "format": "uuid"
    },
    "demand_route_id": {
      "type": "string",
      "format": "uuid",
      "description": "Required for supply-pack / demand-edge effects; omit for INSTALL_STACK_PRODUCT."
    },
    "demand_partner_id": {
      "type": "string",
      "format": "uuid",
      "description": "Required for supply-pack / demand-edge effects; omit for INSTALL_STACK_PRODUCT."
    },
    "buyer_seat": {
      "type": "string"
    },
    "actor_label": {
      "type": "string"
    },
    "terms_snapshot": {
      "type": "string",
      "description": "Opaque terms or stack-product install config JSON."
    },
    "effect": {
      "$ref": "#/components/schemas/ListingActivationEffect"
    }
  }
}
ListingActivationList

schemas/ListingActivation

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ListingActivation"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
PasteSiteCreate

{
  "type": "object",
  "required": [
    "site"
  ],
  "properties": {
    "site": {
      "type": "string",
      "description": "Bare domain or URL pasted by the publisher (normalized to hostname)."
    }
  }
}
PasteSiteResult

schemas/Placementschemas/MarketplaceListing

{
  "type": "object",
  "required": [
    "domain",
    "placement",
    "listing"
  ],
  "properties": {
    "domain": {
      "type": "string"
    },
    "placement": {
      "$ref": "#/components/schemas/Placement"
    },
    "listing": {
      "$ref": "#/components/schemas/MarketplaceListing"
    }
  }
}
PathReceiptNodeRole

{
  "type": "string",
  "enum": [
    "SUPPLY",
    "RESELLER",
    "DEMAND",
    "BUYER",
    "VENDOR"
  ]
}
PathReceiptFeeKind

{
  "type": "string",
  "enum": [
    "LAKE_DISCOVERY",
    "CLEARING",
    "SUPPLY_TERMS",
    "DEMAND_MARGIN",
    "VENDOR_PRODUCT",
    "BUNDLE_PREMIUM",
    "PLATFORM"
  ]
}
PathReceiptDealContext

{
  "type": "string",
  "enum": [
    "OPEN",
    "MARKETPLACE",
    "DEAL_PREFERRED",
    "DEAL_GUARANTEED",
    "DEAL_PRIVATE",
    "FEDERATED"
  ]
}
PathReceiptNode

schemas/PathReceiptNodeRole

{
  "type": "object",
  "required": [
    "role",
    "hop_index"
  ],
  "properties": {
    "role": {
      "$ref": "#/components/schemas/PathReceiptNodeRole"
    },
    "tenant_id": {
      "type": "string"
    },
    "display_name": {
      "type": "string"
    },
    "schain_asi": {
      "type": "string"
    },
    "schain_sid": {
      "type": "string"
    },
    "hop_index": {
      "type": "integer",
      "format": "int32",
      "description": "-1 for receipt-only VENDOR nodes"
    },
    "attestation_id": {
      "type": "string"
    }
  }
}
PathReceiptFeeLine

schemas/PathReceiptNodeRoleschemas/PathReceiptFeeKind

{
  "type": "object",
  "required": [
    "payee_role",
    "kind",
    "fee_type",
    "value",
    "amount"
  ],
  "properties": {
    "payee_role": {
      "$ref": "#/components/schemas/PathReceiptNodeRole"
    },
    "payee_tenant_id": {
      "type": "string"
    },
    "kind": {
      "$ref": "#/components/schemas/PathReceiptFeeKind"
    },
    "fee_type": {
      "type": "string",
      "enum": [
        "REVSHARE",
        "CPM",
        "FLAT"
      ],
      "x-enum-varnames": [
        "PathReceiptFeeLineFeeTypeREVSHARE",
        "PathReceiptFeeLineFeeTypeCPM",
        "PathReceiptFeeLineFeeTypeFLAT"
      ]
    },
    "value": {
      "type": "string"
    },
    "amount": {
      "type": "string"
    }
  }
}
PathReceipt

schemas/PathReceiptNodeschemas/PathReceiptFeeLineschemas/PathReceiptDealContext

{
  "type": "object",
  "required": [
    "request_id",
    "fill_id",
    "tenant_id",
    "occurred_at",
    "path_nodes",
    "fee_lines",
    "deal_context",
    "hop_count",
    "gross_cpm",
    "net_cpm",
    "currency"
  ],
  "description": "Per-fill path + economics projection (design 25 §7).",
  "properties": {
    "request_id": {
      "type": "string"
    },
    "fill_id": {
      "type": "string"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "occurred_at": {
      "type": "string",
      "format": "date-time"
    },
    "path_nodes": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PathReceiptNode"
      }
    },
    "fee_lines": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PathReceiptFeeLine"
      }
    },
    "deal_context": {
      "$ref": "#/components/schemas/PathReceiptDealContext"
    },
    "privacy_mode": {
      "type": "string"
    },
    "seller_of_record": {
      "type": "object",
      "properties": {
        "tenant_id": {
          "type": "string"
        },
        "sellers_json_seller_id": {
          "type": "string"
        }
      }
    },
    "hop_count": {
      "type": "integer",
      "format": "int32"
    },
    "effective_max_hops": {
      "type": "integer",
      "format": "int32"
    },
    "gross_cpm": {
      "type": "string"
    },
    "net_cpm": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    }
  }
}
ProposalState

{
  "type": "string",
  "enum": [
    "OPEN",
    "COUNTERED",
    "APPROVED",
    "REJECTED",
    "WITHDRAWN",
    "EXPIRED"
  ]
}
ProposalPartyRole

{
  "type": "string",
  "enum": [
    "PROPOSER",
    "OWNER"
  ]
}
ListingProposalTerms

schemas/ListingPaymentProfile

{
  "type": "object",
  "description": "Bilateral terms payload stored as jsonb on listing_proposal (design 25 §6.2).",
  "properties": {
    "fee_type": {
      "type": "string",
      "enum": [
        "REVSHARE",
        "CPM",
        "FLAT"
      ],
      "x-enum-varnames": [
        "ListingProposalTermsFeeTypeREVSHARE",
        "ListingProposalTermsFeeTypeCPM",
        "ListingProposalTermsFeeTypeFLAT"
      ]
    },
    "fee_value": {
      "type": "string",
      "description": "Decimal string."
    },
    "max_qps": {
      "type": "integer",
      "format": "int32"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "hop_policy": {
      "type": "object",
      "properties": {
        "max_hops": {
          "type": "integer",
          "format": "int32"
        },
        "allow_reseller": {
          "type": "boolean"
        }
      }
    },
    "seller_of_record": {
      "type": "object",
      "properties": {
        "tenant_id": {
          "type": "string",
          "format": "uuid"
        },
        "sellers_json_seller_id": {
          "type": "string"
        }
      }
    },
    "flight": {
      "type": "object",
      "properties": {
        "start_unix": {
          "type": "integer",
          "format": "int64"
        },
        "end_unix": {
          "type": "integer",
          "format": "int64"
        }
      }
    },
    "payment_profile": {
      "$ref": "#/components/schemas/ListingPaymentProfile"
    }
  }
}
ListingProposal

schemas/ProposalPartyRoleschemas/ProposalStateschemas/ListingProposalTerms

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "counterparty_tenant_id",
    "party_role",
    "listing_id",
    "thread_id",
    "revision",
    "state",
    "idempotency_key"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "counterparty_tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "party_role": {
      "$ref": "#/components/schemas/ProposalPartyRole"
    },
    "listing_id": {
      "type": "string",
      "format": "uuid"
    },
    "thread_id": {
      "type": "string",
      "format": "uuid"
    },
    "revision": {
      "type": "integer",
      "format": "int32"
    },
    "last_actor_tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "state": {
      "$ref": "#/components/schemas/ProposalState"
    },
    "terms": {
      "$ref": "#/components/schemas/ListingProposalTerms"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    },
    "idempotency_key": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ListingProposalCreate

schemas/ListingProposalTerms

{
  "type": "object",
  "required": [
    "listing_id",
    "terms",
    "reason"
  ],
  "properties": {
    "listing_id": {
      "type": "string",
      "format": "uuid"
    },
    "terms": {
      "$ref": "#/components/schemas/ListingProposalTerms"
    },
    "reason": {
      "type": "string",
      "description": "Recorded in the audit envelope."
    }
  }
}
ListingProposalMutate

{
  "type": "object",
  "required": [
    "expected_revision",
    "reason"
  ],
  "properties": {
    "expected_revision": {
      "type": "integer",
      "format": "int32"
    },
    "reason": {
      "type": "string"
    }
  }
}
ListingProposalCounter

schemas/ListingProposalMutateschemas/ListingProposalTerms

{
  "allOf": [
    {
      "$ref": "#/components/schemas/ListingProposalMutate"
    },
    {
      "type": "object",
      "required": [
        "terms"
      ],
      "properties": {
        "terms": {
          "$ref": "#/components/schemas/ListingProposalTerms"
        }
      }
    }
  ]
}
ListingProposalApprove

schemas/ListingProposalMutate

{
  "allOf": [
    {
      "$ref": "#/components/schemas/ListingProposalMutate"
    },
    {
      "type": "object",
      "properties": {
        "demand_route_id": {
          "type": "string",
          "format": "uuid"
        },
        "demand_partner_id": {
          "type": "string",
          "format": "uuid"
        },
        "buyer_seat": {
          "type": "string"
        },
        "actor_label": {
          "type": "string"
        },
        "activation_idempotency_key": {
          "type": "string",
          "description": "Idempotency key for the ListingActivation row created on approve."
        }
      }
    }
  ]
}
ListingProposalApproveResult

schemas/ListingProposalschemas/ListingActivation

{
  "type": "object",
  "required": [
    "proposal",
    "audit_id"
  ],
  "properties": {
    "proposal": {
      "$ref": "#/components/schemas/ListingProposal"
    },
    "activation": {
      "$ref": "#/components/schemas/ListingActivation"
    },
    "audit_id": {
      "type": "string",
      "description": "AuditEnvelope id for this mutation."
    }
  }
}
PlacementMarketplaceMembership

{
  "type": "object",
  "required": [
    "marketplace_ids"
  ],
  "properties": {
    "marketplace_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Opaque cursor for the next page of ids; absent on the last page."
    }
  }
}
PlacementDemandRouteMembership

{
  "type": "object",
  "required": [
    "demand_route_ids"
  ],
  "properties": {
    "demand_route_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Opaque cursor for the next page of ids; absent on the last page."
    }
  }
}
ResolvedMarketplaceRoutes

{
  "type": "object",
  "description": "The result of resolvePlacementMarketplaces's dry run (P3-03 \"marketplace resolve\"): every ACTIVE demand route id that would be merged onto the placement at compile time via its marketplace membership.\n",
  "required": [
    "demand_route_ids"
  ],
  "properties": {
    "demand_route_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    }
  }
}
Advertiser

schemas/LifecycleStatus

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "ref",
    "name",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "ref": {
      "type": "string",
      "description": "Short per-tenant reference code."
    },
    "name": {
      "type": "string"
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels (GC-03). At serve time a line item's effective label set is the union of its advertiser's, campaign order's, and its own labels; no two winners sharing a label serve into one slate/pod or one multi-opportunity request.\n"
    },
    "agency": {
      "type": "string",
      "description": "Buying agency (SR-1011 commercial metadata)."
    },
    "sales_owner": {
      "type": "string",
      "description": "Account / sales owner on the seller side."
    },
    "account_owner_user_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The app user who owns the account relationship (SR-1218): a user of the same tenant (references app_user). Null / omitted = unassigned; sales_owner stays the free-text seller-side name for commercial metadata.\n"
    },
    "notes": {
      "type": "string"
    },
    "billing_contact_name": {
      "type": "string"
    },
    "billing_contact_email": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
AdvertiserCreate

{
  "type": "object",
  "required": [
    "ref",
    "name"
  ],
  "properties": {
    "ref": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels (GC-03). At serve time a line item's effective label set is the union of its advertiser's, campaign order's, and its own labels; no two winners sharing a label serve into one slate/pod or one multi-opportunity request.\n"
    },
    "agency": {
      "type": "string",
      "description": "Buying agency (SR-1011 commercial metadata)."
    },
    "sales_owner": {
      "type": "string",
      "description": "Account / sales owner on the seller side."
    },
    "account_owner_user_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The app user who owns the account relationship (SR-1218): a user of the same tenant (references app_user). Null / omitted = unassigned; sales_owner stays the free-text seller-side name for commercial metadata.\n"
    },
    "notes": {
      "type": "string"
    },
    "billing_contact_name": {
      "type": "string"
    },
    "billing_contact_email": {
      "type": "string"
    }
  }
}
AdvertiserUpdate

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels (GC-03). At serve time a line item's effective label set is the union of its advertiser's, campaign order's, and its own labels; no two winners sharing a label serve into one slate/pod or one multi-opportunity request.\n"
    },
    "agency": {
      "type": "string",
      "description": "Buying agency (SR-1011 commercial metadata)."
    },
    "sales_owner": {
      "type": "string",
      "description": "Account / sales owner on the seller side."
    },
    "account_owner_user_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The app user who owns the account relationship (SR-1218): a user of the same tenant (references app_user). Null / omitted = unassigned; sales_owner stays the free-text seller-side name for commercial metadata.\n"
    },
    "notes": {
      "type": "string"
    },
    "billing_contact_name": {
      "type": "string"
    },
    "billing_contact_email": {
      "type": "string"
    }
  }
}
AdvertiserList

schemas/Advertiser

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Advertiser"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
FeeScheduleScope

{
  "type": "string",
  "description": "The resolution level a fee schedule applies at (riptide.common.v1.FeeScope). Precedence, most to least specific: PLACEMENT > PUBLISHER > MARKETPLACE > DEMAND_PARTNER > DEFAULT (docs/design/08-economics.md). At most one schedule per tenant+scope+scope_id.\n",
  "enum": [
    "PLACEMENT",
    "PUBLISHER",
    "MARKETPLACE",
    "DEMAND_PARTNER",
    "DEFAULT",
    "STACK_PRODUCT",
    "LISTING"
  ]
}
FeeKind

{
  "type": "string",
  "description": "Which economics-phase leg a fee-schedule line funds within its scope bundle (riptide.common.v1.FeeKind, docs/design/08-economics.md): DEMAND is the buyer-side revenue share/cost, MARKETPLACE the marketplace cut (platform take), PUBLISHER the publisher revenue share/fixed CPM, SERVING the flat serving/stitch-adjacent fee.\n",
  "enum": [
    "platform",
    "demand",
    "publisher",
    "serving",
    "vendor",
    "lake",
    "io"
  ]
}
FeeMediaKind

{
  "type": "string",
  "description": "Media kind a fee-schedule line is scoped to (riptide.common.v1.FeeMediaKind, SR-1204). Omitted = any media. Within one scope level a line whose media kind matches the priced opportunity wins over the any-media line; a line for another media kind never matches. COMPANION is a display creative filling a companion slot of a video/audio opportunity.\n",
  "enum": [
    "VIDEO",
    "AUDIO",
    "COMPANION",
    "DISPLAY"
  ]
}
FeeType

{
  "type": "string",
  "description": "riptide.common.v1.FeeType — the basis a fee line's value is expressed in.",
  "enum": [
    "REVSHARE",
    "CPM",
    "FLAT"
  ]
}
FeeLine

schemas/FeeKindschemas/FeeTypeschemas/FeeMediaKind

{
  "type": "object",
  "description": "One economics-phase leg's value within a fee-schedule bundle — at most one line per kind (docs/design/08-economics.md \"the same engine produces both the publisher payout and the platform's take\": resolving one scope bundle and reading each kind's line).\n",
  "required": [
    "kind",
    "fee_type",
    "value"
  ],
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/FeeKind"
    },
    "fee_type": {
      "$ref": "#/components/schemas/FeeType"
    },
    "value": {
      "type": "string",
      "description": "Decimal string; a fraction for REVSHARE (e.g. \"0.15\"), money for CPM/FLAT."
    },
    "gross_net": {
      "type": "string",
      "enum": [
        "GROSS",
        "NET"
      ],
      "default": "NET"
    },
    "cpm_metric": {
      "type": "string",
      "enum": [
        "IMPRESSIONS",
        "FILLS"
      ],
      "default": "IMPRESSIONS",
      "description": "Only meaningful when fee_type is CPM."
    },
    "media_kind": {
      "$ref": "#/components/schemas/FeeMediaKind"
    }
  }
}
FeeSchedule

schemas/FeeScheduleScopeschemas/FeeLineschemas/LifecycleStatus

{
  "type": "object",
  "description": "Tenant-configured pricing rules by scope — docs/design/08-economics.md — already consumed by the runtime pricing engine's scope-precedence resolver (libs/plan.ResolveFeeSchedule, P3-06).\n",
  "required": [
    "id",
    "tenant_id",
    "name",
    "scope",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "scope": {
      "$ref": "#/components/schemas/FeeScheduleScope"
    },
    "scope_id": {
      "type": "string",
      "description": "Id of the scoped entity (placement/publisher/marketplace/demand partner); empty for DEFAULT."
    },
    "lines": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FeeLine"
      }
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
FeeScheduleCreate

schemas/FeeScheduleScopeschemas/FeeLine

{
  "type": "object",
  "required": [
    "name",
    "lines"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "scope": {
      "$ref": "#/components/schemas/FeeScheduleScope"
    },
    "scope_id": {
      "type": "string"
    },
    "lines": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/components/schemas/FeeLine"
      }
    }
  }
}
FeeScheduleUpdate

schemas/FeeLine

{
  "type": "object",
  "required": [
    "name",
    "lines"
  ],
  "description": "scope and scope_id are immutable after creation (create a new bundle instead).",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "lines": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/components/schemas/FeeLine"
      }
    }
  }
}
FeeScheduleList

schemas/FeeSchedule

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FeeSchedule"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
FeeSchedulePreviewRequest

schemas/FeeKindschemas/FeeMediaKind

{
  "type": "object",
  "required": [
    "kind"
  ],
  "description": "A scope-precedence dry run (P3-06) — which saved fee schedule would apply.",
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/FeeKind"
    },
    "placement_id": {
      "type": "string",
      "format": "uuid"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid"
    },
    "marketplace_id": {
      "type": "string",
      "format": "uuid"
    },
    "demand_partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "media_kind": {
      "$ref": "#/components/schemas/FeeMediaKind"
    }
  }
}
FeeSchedulePreviewResponse

schemas/FeeScheduleScopeschemas/FeeLine

{
  "type": "object",
  "required": [
    "resolved"
  ],
  "properties": {
    "resolved": {
      "type": "boolean",
      "description": "false when no fee schedule (not even a DEFAULT) matched."
    },
    "fee_schedule_id": {
      "type": "string",
      "format": "uuid"
    },
    "scope": {
      "$ref": "#/components/schemas/FeeScheduleScope"
    },
    "line": {
      "$ref": "#/components/schemas/FeeLine"
    }
  }
}
ModelKind

{
  "type": "string",
  "description": "Decisioner integration kind (proto decisionv1's INTEGRATION_KIND family, mirrored as plain text in model_registry.kind).",
  "enum": [
    "BASELINE",
    "SIDECAR",
    "EXTERNAL_ENDPOINT"
  ]
}
ModelAssignmentMode

{
  "type": "string",
  "description": "How a model may currently serve for a decision point (docs/spec/decisioners/README.md \"Shadow, live, and replay\").",
  "enum": [
    "SHADOW",
    "BOUNDED_AB",
    "LIVE"
  ]
}
ModelRegistryEntry

schemas/ModelKind

{
  "type": "object",
  "description": "AI-0C model registry entry (migrations/postgres/0023_model_registry). tenant_id absent means a platform-shared model (Riptide-shipped baseline/model), visible to every tenant but writable only by the operator.\n",
  "required": [
    "id",
    "decision_point",
    "name",
    "version",
    "kind",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Absent for a platform-shared model."
    },
    "decision_point": {
      "type": "string",
      "description": "One of docs/spec/decisioners/README.md's decision points: bid, floor, traffic_shape, pace, creative, audience, insight, anomaly."
    },
    "name": {
      "type": "string"
    },
    "version": {
      "type": "string"
    },
    "entitlement": {
      "type": "string",
      "description": "Feature gating this model; empty means not entitlement-gated."
    },
    "kind": {
      "$ref": "#/components/schemas/ModelKind"
    },
    "config": {
      "type": "object",
      "additionalProperties": true,
      "description": "Endpoint/weights config for this model — never a secret (500-security-privacy)."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ModelCreateRequest

schemas/ModelKind

{
  "type": "object",
  "required": [
    "decision_point",
    "name",
    "version",
    "kind"
  ],
  "properties": {
    "decision_point": {
      "type": "string",
      "description": "One of docs/spec/decisioners/README.md's decision points: bid, floor, traffic_shape, pace, creative, audience, insight, anomaly."
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "version": {
      "type": "string",
      "minLength": 1
    },
    "entitlement": {
      "type": "string"
    },
    "kind": {
      "$ref": "#/components/schemas/ModelKind"
    },
    "config": {
      "type": "object",
      "additionalProperties": true,
      "description": "Endpoint/weights config for this model — never a secret."
    }
  }
}
ModelAssignmentRequest

schemas/ModelAssignmentMode

{
  "type": "object",
  "required": [
    "decision_point",
    "mode"
  ],
  "properties": {
    "decision_point": {
      "type": "string"
    },
    "mode": {
      "$ref": "#/components/schemas/ModelAssignmentMode"
    },
    "traffic_pct": {
      "type": "string",
      "description": "Decimal percentage as a string in [0,100], stored in model_assignment.traffic_pct."
    }
  }
}
ModelAssignment

schemas/ModelAssignmentMode

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "model_id",
    "decision_point",
    "mode",
    "traffic_pct"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "model_id": {
      "type": "string",
      "format": "uuid"
    },
    "decision_point": {
      "type": "string"
    },
    "mode": {
      "$ref": "#/components/schemas/ModelAssignmentMode"
    },
    "traffic_pct": {
      "type": "string",
      "description": "Decimal percentage as a string."
    }
  }
}
ModelEvaluationResult

{
  "type": "string",
  "enum": [
    "PENDING",
    "PASSED",
    "FAILED"
  ]
}
ModelEvaluationRunRequest

schemas/ModelEvaluationResult

{
  "type": "object",
  "required": [
    "decision_point",
    "objective",
    "result"
  ],
  "properties": {
    "decision_point": {
      "type": "string"
    },
    "objective": {
      "type": "string",
      "minLength": 1
    },
    "baseline_metric": {
      "type": "string",
      "description": "Decimal metric value as a string."
    },
    "candidate_metric": {
      "type": "string",
      "description": "Decimal metric value as a string."
    },
    "lift_pct": {
      "type": "string",
      "description": "Decimal lift percentage as a string."
    },
    "result": {
      "$ref": "#/components/schemas/ModelEvaluationResult"
    },
    "criteria_id": {
      "type": "string",
      "format": "uuid",
      "description": "The model evaluation criteria row (model_eval_criteria) the run was judged by (SR-1213 / SR-005): a PASSED result is never self-attested — the evaluation writer checks the metrics against the named criteria. Omit only for runs that record a baseline without a promotion gate.\n"
    }
  }
}
ModelEvaluationRun

schemas/ModelEvaluationResult

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "model_id",
    "decision_point",
    "objective",
    "result",
    "recorded_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "model_id": {
      "type": "string",
      "format": "uuid"
    },
    "decision_point": {
      "type": "string"
    },
    "objective": {
      "type": "string"
    },
    "baseline_metric": {
      "type": "string"
    },
    "candidate_metric": {
      "type": "string"
    },
    "lift_pct": {
      "type": "string"
    },
    "result": {
      "$ref": "#/components/schemas/ModelEvaluationResult"
    },
    "recorded_at": {
      "type": "string",
      "format": "date-time"
    },
    "criteria_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The model_eval_criteria row the run was judged by; null for runs recorded before the criteria gate (SR-1213)."
    },
    "evaluated_by": {
      "type": "string",
      "readOnly": true,
      "description": "Actor label of the evaluation writer that judged the run (SR-1213); empty for legacy rows."
    },
    "audit_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "readOnly": true,
      "description": "The audit_log envelope the evaluation writer produced for this run (SR-1213); null when no envelope was written."
    }
  }
}
PlatformRatePlan

{
  "type": "object",
  "description": "Platform rate plan assigned to a tenant (migrations/postgres/0005 + 0017).",
  "required": [
    "id",
    "name",
    "model",
    "currency"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "model": {
      "type": "string",
      "description": "FLAT|PER_SEAT|PER_IMPRESSION|PCT_SPEND|INFRA_PASSTHROUGH|HYBRID"
    },
    "currency": {
      "type": "string"
    },
    "config_json": {
      "type": "string",
      "description": "Opaque plan config JSON (decimal money as strings)."
    }
  }
}
RatePlanCreate

{
  "type": "object",
  "description": "Request body for POST /v1/operator/rate-plans (RIP-148 commercial catalog).",
  "required": [
    "name",
    "model",
    "currency"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "model": {
      "type": "string",
      "description": "FLAT|PER_SEAT|PER_IMPRESSION|PCT_SPEND|INFRA_PASSTHROUGH|HYBRID"
    },
    "currency": {
      "type": "string"
    },
    "config_json": {
      "type": "string",
      "description": "Opaque plan config JSON (decimal money as strings)."
    }
  }
}
PlatformRatePlanList

schemas/PlatformRatePlan

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PlatformRatePlan"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
UsageRecord

schemas/UsageSource

{
  "type": "object",
  "required": [
    "tenant_id",
    "metric",
    "quantity",
    "unit"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "period_start": {
      "type": "string",
      "format": "date-time"
    },
    "period_end": {
      "type": "string",
      "format": "date-time"
    },
    "metric": {
      "type": "string"
    },
    "quantity": {
      "type": "string",
      "description": "Decimal string."
    },
    "unit": {
      "type": "string"
    },
    "source_hash": {
      "type": "string"
    },
    "sources": {
      "type": "array",
      "maxItems": 20000,
      "description": "Stable source contributions for ingestion; omitted from aggregate reports.",
      "items": {
        "$ref": "#/components/schemas/UsageSource"
      }
    },
    "prepaid_assessed": {
      "type": "boolean",
      "readOnly": true,
      "description": "Usage already assessed through prepaid billing, including exhausted or waived charges; excluded from later monthly usage collection."
    }
  }
}
UsageSource

{
  "type": "object",
  "required": [
    "source_id",
    "quantity"
  ],
  "properties": {
    "source_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256
    },
    "quantity": {
      "type": "string",
      "description": "Nonnegative decimal contribution with at most 18 fractional digits.",
      "pattern": "^(0|[1-9][0-9]{0,13})(\\.[0-9]{1,18})?$"
    }
  }
}
ReconciliationPartnerKind

{
  "type": "string",
  "enum": [
    "DEMAND_PARTNER",
    "PUBLISHER"
  ],
  "x-enum-varnames": [
    "ReconciliationPartnerKindDEMANDPARTNER",
    "ReconciliationPartnerKindPUBLISHER"
  ]
}
ReconciliationStatementRow

{
  "type": "object",
  "required": [
    "day",
    "impressions",
    "amount"
  ],
  "properties": {
    "day": {
      "type": "string",
      "format": "date",
      "description": "Statement day (partner's reporting day, UTC)."
    },
    "impressions": {
      "type": "integer",
      "format": "int64"
    },
    "amount": {
      "type": "string",
      "description": "Decimal string in the statement currency (4 dp)."
    },
    "external_ref": {
      "type": "string",
      "description": "Partner-side line reference (deal id, seat, placement)."
    }
  }
}
ReconciliationStatementImport

schemas/ReconciliationPartnerKindschemas/ReconciliationStatementRow

{
  "type": "object",
  "required": [
    "partner_kind",
    "partner_id",
    "period_start",
    "period_end",
    "currency",
    "rows"
  ],
  "properties": {
    "partner_kind": {
      "$ref": "#/components/schemas/ReconciliationPartnerKind"
    },
    "partner_id": {
      "type": "string",
      "format": "uuid",
      "description": "demand_partner.id or publisher.id in this tenant."
    },
    "period_start": {
      "type": "string",
      "format": "date"
    },
    "period_end": {
      "type": "string",
      "format": "date",
      "description": "Inclusive."
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "source": {
      "type": "string",
      "enum": [
        "CSV",
        "API"
      ],
      "x-enum-varnames": [
        "ReconciliationStatementSourceCSV",
        "ReconciliationStatementSourceAPI"
      ],
      "description": "Where the rows came from; informational."
    },
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReconciliationStatementRow"
      }
    }
  }
}
ReconciliationStatement

schemas/ReconciliationPartnerKindschemas/ReconciliationStatementRow

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "partner_kind",
    "partner_id",
    "period_start",
    "period_end",
    "currency",
    "row_count",
    "total_impressions",
    "total_amount",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "partner_kind": {
      "$ref": "#/components/schemas/ReconciliationPartnerKind"
    },
    "partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "period_start": {
      "type": "string",
      "format": "date"
    },
    "period_end": {
      "type": "string",
      "format": "date"
    },
    "currency": {
      "type": "string"
    },
    "source": {
      "type": "string"
    },
    "row_count": {
      "type": "integer"
    },
    "total_impressions": {
      "type": "integer",
      "format": "int64"
    },
    "total_amount": {
      "type": "string",
      "description": "Decimal string (4 dp)."
    },
    "rows": {
      "type": "array",
      "description": "Present on getReconciliationStatement only.",
      "items": {
        "$ref": "#/components/schemas/ReconciliationStatementRow"
      }
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ReconciliationStatementList

schemas/ReconciliationStatement

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReconciliationStatement"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ReconciliationCompareRequest

{
  "type": "object",
  "required": [
    "statement_id"
  ],
  "properties": {
    "statement_id": {
      "type": "string",
      "format": "uuid"
    },
    "tolerance_pct": {
      "type": "string",
      "description": "Decimal percent (e.g. \"2.5\"); a day whose |delta| / platform amount is within it is MATCHED. Default 0 (exact)."
    },
    "tolerance_amount": {
      "type": "string",
      "description": "Absolute decimal tolerance in the statement currency; a day within either tolerance is MATCHED."
    }
  }
}
ReconciliationLine

{
  "type": "object",
  "required": [
    "day",
    "statement_impressions",
    "platform_impressions",
    "statement_amount",
    "platform_amount",
    "delta_amount",
    "within_tolerance"
  ],
  "properties": {
    "day": {
      "type": "string",
      "format": "date"
    },
    "statement_impressions": {
      "type": "integer",
      "format": "int64"
    },
    "platform_impressions": {
      "type": "integer",
      "format": "int64"
    },
    "statement_amount": {
      "type": "string"
    },
    "platform_amount": {
      "type": "string"
    },
    "delta_amount": {
      "type": "string",
      "description": "statement − platform (decimal, 4 dp)."
    },
    "within_tolerance": {
      "type": "boolean"
    }
  }
}
ReconciliationReportStatus

{
  "type": "string",
  "enum": [
    "MATCHED",
    "DISCREPANT"
  ],
  "x-enum-varnames": [
    "ReconciliationReportStatusMATCHED",
    "ReconciliationReportStatusDISCREPANT"
  ]
}
ReconciliationReport

schemas/ReconciliationPartnerKindschemas/ReconciliationReportStatusschemas/ReconciliationLine

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "statement_id",
    "partner_kind",
    "partner_id",
    "status",
    "currency",
    "statement_total",
    "platform_total",
    "delta_total",
    "discrepant_days",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "statement_id": {
      "type": "string",
      "format": "uuid"
    },
    "partner_kind": {
      "$ref": "#/components/schemas/ReconciliationPartnerKind"
    },
    "partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "status": {
      "$ref": "#/components/schemas/ReconciliationReportStatus"
    },
    "currency": {
      "type": "string"
    },
    "tolerance_pct": {
      "type": "string"
    },
    "tolerance_amount": {
      "type": "string"
    },
    "statement_total": {
      "type": "string"
    },
    "platform_total": {
      "type": "string"
    },
    "delta_total": {
      "type": "string"
    },
    "discrepant_days": {
      "type": "integer"
    },
    "lines": {
      "type": "array",
      "description": "Per-day comparison; present on getReconciliationReport and the compare response.",
      "items": {
        "$ref": "#/components/schemas/ReconciliationLine"
      }
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "adjustment_memo": {
      "type": "string",
      "nullable": true,
      "maxLength": 2000,
      "readOnly": true,
      "description": "Human explanation of how the discrepancy was settled (SR-1218); set via setReconciliationAdjustmentMemo, null until then."
    },
    "adjustment_memo_by": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "readOnly": true,
      "description": "The app user who recorded the adjustment memo; null until a memo is set."
    },
    "adjustment_memo_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "readOnly": true,
      "description": "When the adjustment memo was recorded; null until a memo is set."
    }
  }
}
ReconciliationReportList

schemas/ReconciliationReport

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReconciliationReport"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ReconciliationAdjustmentMemoRequest

{
  "type": "object",
  "description": "Body for setReconciliationAdjustmentMemo (SR-1218).",
  "required": [
    "memo"
  ],
  "properties": {
    "memo": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "The adjustment memo text; replaces any earlier memo on the report."
    }
  }
}
UsageRecordList

schemas/UsageRecord

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/UsageRecord"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
CostTelemetry

{
  "type": "object",
  "description": "Derived per-usage-record cost telemetry. id/source_hash is the usage_record source_hash; cost_usd is computed from libs/billing.DefaultCostRates over the persisted metered quantity.\n",
  "required": [
    "id",
    "tenant_id",
    "period_start",
    "period_end",
    "metric",
    "quantity",
    "unit",
    "cost_usd",
    "currency",
    "source_hash"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Stable id equal to source_hash."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "period_start": {
      "type": "string",
      "format": "date-time"
    },
    "period_end": {
      "type": "string",
      "format": "date-time"
    },
    "metric": {
      "type": "string"
    },
    "quantity": {
      "type": "string",
      "description": "Decimal string from the usage record."
    },
    "unit": {
      "type": "string"
    },
    "cost_usd": {
      "type": "string",
      "description": "Decimal USD cost string with 4 decimal places."
    },
    "currency": {
      "type": "string",
      "enum": [
        "USD"
      ]
    },
    "source_hash": {
      "type": "string"
    }
  }
}
CostTelemetryList

schemas/CostTelemetry

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CostTelemetry"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
PrepaidBalance

{
  "type": "object",
  "required": [
    "tenant_id",
    "currency",
    "balance"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "currency": {
      "type": "string"
    },
    "balance": {
      "type": "string",
      "description": "Decimal string; sum of signed ledger amounts (4 dp)."
    }
  }
}
PrepaidTopUpCreate

{
  "type": "object",
  "required": [
    "amount",
    "currency"
  ],
  "properties": {
    "amount": {
      "type": "string",
      "description": "Positive decimal string credit (4 dp)."
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "reason": {
      "type": "string",
      "description": "Optional memo for the ledger row."
    }
  }
}
PrepaidLedgerEntry

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "amount",
    "currency",
    "created_at",
    "idempotency_key"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "amount": {
      "type": "string",
      "description": "Signed decimal string (4 dp)."
    },
    "currency": {
      "type": "string"
    },
    "reason": {
      "type": "string"
    },
    "actor_label": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "idempotency_key": {
      "type": "string"
    },
    "balance_after": {
      "type": "string",
      "description": "Balance for currency after this entry."
    }
  }
}
PrepaidTopUpResponse

schemas/PrepaidLedgerEntry

{
  "type": "object",
  "required": [
    "entry"
  ],
  "properties": {
    "entry": {
      "$ref": "#/components/schemas/PrepaidLedgerEntry"
    },
    "audit_id": {
      "type": "string",
      "description": "AuditEnvelope id for this mutation."
    }
  }
}
TenantQuotaState

{
  "type": "object",
  "description": "The meter's serving verdict for a tenant (SR-1204; tenant_quota_state). state is what planc projects onto Tenant.serving_state: serve answers quota_exceeded / serving_suspended from it. used and quota_limit are decimal strings in the metric's unit (requests for requests_per_day; settlement money for prepaid_balance).\n",
  "required": [
    "tenant_id",
    "state"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "state": {
      "type": "string",
      "enum": [
        "ok",
        "quota_exceeded",
        "suspended"
      ]
    },
    "metric": {
      "type": "string",
      "description": "requests_per_day | prepaid_balance; empty when nothing is metered."
    },
    "used": {
      "type": "string",
      "description": "Decimal string."
    },
    "quota_limit": {
      "type": "string",
      "description": "Decimal string; 0 = unlimited."
    },
    "period_start": {
      "type": "string",
      "format": "date-time"
    },
    "period_end": {
      "type": "string",
      "format": "date-time"
    },
    "reason": {
      "type": "string"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
FxRate

{
  "type": "object",
  "required": [
    "currency",
    "rate_to_usd",
    "as_of"
  ],
  "properties": {
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3,
      "description": "ISO 4217 code."
    },
    "rate_to_usd": {
      "type": "string",
      "description": "Decimal string: one unit of currency in USD."
    },
    "as_of": {
      "type": "string",
      "format": "date-time",
      "description": "The source snapshot date."
    },
    "source": {
      "type": "string"
    },
    "fetched_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
FxRateList

schemas/FxRate

{
  "type": "object",
  "required": [
    "items",
    "age_seconds"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FxRate"
      }
    },
    "age_seconds": {
      "type": "integer",
      "format": "int64",
      "description": "now - newest as_of over the whole cache; -1 when the cache is empty."
    },
    "stale": {
      "type": "boolean",
      "description": "age_seconds above the configured RIPTIDE_FX_RATES_MAX_AGE_SECONDS (default 48h)."
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
FxRefreshResult

{
  "type": "object",
  "required": [
    "currencies",
    "as_of"
  ],
  "properties": {
    "currencies": {
      "type": "integer",
      "format": "int32",
      "description": "Rates written."
    },
    "as_of": {
      "type": "string",
      "format": "date-time"
    },
    "source": {
      "type": "string"
    }
  }
}
PlatformInvoice

schemas/InvoiceStatusschemas/FxSnapshotschemas/InvoiceTaxschemas/PlatformInvoiceLine

{
  "type": "object",
  "required": [
    "id",
    "tenant_id",
    "period_start",
    "period_end",
    "currency",
    "total",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "period_start": {
      "type": "string",
      "format": "date-time"
    },
    "period_end": {
      "type": "string",
      "format": "date-time"
    },
    "currency": {
      "type": "string"
    },
    "total": {
      "type": "string",
      "description": "Decimal string."
    },
    "status": {
      "$ref": "#/components/schemas/InvoiceStatus"
    },
    "external_ref": {
      "type": "string"
    },
    "number": {
      "type": "string",
      "nullable": true,
      "description": "Sequential invoice number assigned at ISSUED (per tenant, gap-free); null before."
    },
    "issued_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the invoice became ISSUED; null before."
    },
    "due_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "Payment due date from the tenant's terms; null before ISSUED."
    },
    "paid_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the invoice became PAID; null otherwise."
    },
    "voided_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the invoice became VOID; null otherwise."
    },
    "fx_snapshot": {
      "nullable": true,
      "description": "FX rates frozen at ISSUED for lines billed in another currency; null before ISSUED or when no conversion applied.",
      "allOf": [
        {
          "$ref": "#/components/schemas/FxSnapshot"
        }
      ]
    },
    "tax": {
      "nullable": true,
      "description": "Tax computed at ISSUED through the tax seam; null before ISSUED or when no tax applies.",
      "allOf": [
        {
          "$ref": "#/components/schemas/InvoiceTax"
        }
      ]
    },
    "lines": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PlatformInvoiceLine"
      }
    }
  }
}
PlatformInvoiceLine

{
  "type": "object",
  "required": [
    "description",
    "amount"
  ],
  "properties": {
    "description": {
      "type": "string"
    },
    "metric": {
      "type": "string"
    },
    "quantity": {
      "type": "string"
    },
    "unit_price": {
      "type": "string"
    },
    "amount": {
      "type": "string",
      "description": "Decimal string."
    },
    "rate_plan_id": {
      "type": "string",
      "format": "uuid",
      "description": "Catalog plan id stamped at invoice generation (RIP-148)."
    },
    "resolved_rate": {
      "type": "string",
      "description": "L2 rate after ratchet/floor (decimal string)."
    },
    "config_hash": {
      "type": "string",
      "description": "Digest of rate_plan.config_json used for this line."
    }
  }
}
PlatformInvoiceList

schemas/PlatformInvoice

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PlatformInvoice"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ModelRegistryEntryList

schemas/ModelRegistryEntry

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ModelRegistryEntry"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ModelPromoteRequest

schemas/ModelAssignmentMode

{
  "type": "object",
  "required": [
    "decision_point",
    "to_mode",
    "rationale"
  ],
  "properties": {
    "decision_point": {
      "type": "string"
    },
    "from_mode": {
      "allOf": [
        {
          "$ref": "#/components/schemas/ModelAssignmentMode"
        }
      ],
      "description": "Omitted when this promotion has no specific prior mode (e.g. the model's first assignment for this decision point)."
    },
    "to_mode": {
      "$ref": "#/components/schemas/ModelAssignmentMode"
    },
    "evaluation_run_id": {
      "type": "string",
      "format": "uuid",
      "description": "The model_evaluation_run this promotion is based on, if any."
    },
    "rationale": {
      "type": "string",
      "minLength": 1,
      "description": "Why this promotion is happening — recorded on the model_promotion_event row."
    }
  }
}
ModelPromotionEvent

schemas/ModelAssignmentMode

{
  "type": "object",
  "description": "An append-only model_promotion_event row (never edited/deleted after the fact).",
  "required": [
    "id",
    "model_id",
    "decision_point",
    "to_mode",
    "at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "model_id": {
      "type": "string",
      "format": "uuid"
    },
    "decision_point": {
      "type": "string"
    },
    "from_mode": {
      "$ref": "#/components/schemas/ModelAssignmentMode"
    },
    "to_mode": {
      "$ref": "#/components/schemas/ModelAssignmentMode"
    },
    "evaluation_run_id": {
      "type": "string",
      "format": "uuid"
    },
    "rationale": {
      "type": "string"
    },
    "at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DecisionFactSummary

{
  "type": "object",
  "required": [
    "request_id",
    "occurred_at",
    "stage_count"
  ],
  "properties": {
    "request_id": {
      "type": "string"
    },
    "occurred_at": {
      "type": "string",
      "format": "date-time"
    },
    "stage_count": {
      "type": "integer"
    },
    "winner_rationale": {
      "type": "string"
    }
  }
}
DecisionFunnelResponse

schemas/DecisionStageFilterschemas/DecisionFactSummary

{
  "type": "object",
  "required": [
    "source_configured",
    "stages",
    "facts"
  ],
  "properties": {
    "source_configured": {
      "type": "boolean",
      "description": "false when the console has no ClickHouse decision-funnel query source wired."
    },
    "stages": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DecisionStageFilter"
      }
    },
    "facts": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DecisionFactSummary"
      }
    }
  }
}
UserStatus

{
  "type": "string",
  "enum": [
    "ACTIVE",
    "SUSPENDED"
  ],
  "x-enum-varnames": [
    "UserStatusACTIVE",
    "UserStatusSUSPENDED"
  ]
}
User

schemas/UserStatus

{
  "type": "object",
  "description": "A console user — docs/design/02-data-model.md; roles from user_role (RIP-131).",
  "required": [
    "id",
    "tenant_id",
    "email",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "name": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/UserStatus"
    },
    "roles": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "authz.Role names (docs/spec/authz-roles.md)."
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Bound publisher for users holding the publisher role (SR-1010); scopes every portal call."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
UserCreate

{
  "type": "object",
  "required": [
    "email"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "minLength": 1
    },
    "name": {
      "type": "string"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid"
    }
  }
}
UserUpdate

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "roles": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Replaces the user's tenant role set (UX-41). Only tenant-assignable roles (docs/spec/authz-roles.md) are accepted; `operator` and unknown names are rejected 400. An empty array leaves the user with tenant_viewer.\n"
    }
  }
}
UserList

schemas/User

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/User"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
AuthConfig

{
  "type": "object",
  "required": [
    "public_signup"
  ],
  "properties": {
    "public_signup": {
      "type": "boolean"
    }
  }
}
AuthAccepted

{
  "type": "object",
  "required": [
    "ok"
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    }
  }
}
AuthSignupRequest

{
  "type": "object",
  "required": [
    "email",
    "tenant_name"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email"
    },
    "name": {
      "type": "string"
    },
    "tenant_name": {
      "type": "string",
      "minLength": 1
    },
    "slug": {
      "type": "string"
    },
    "region": {
      "type": "string"
    },
    "cell_id": {
      "type": "string"
    }
  }
}
AuthMagicLinkRequest

{
  "type": "object",
  "required": [
    "email"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email"
    },
    "tenant_slug": {
      "type": "string"
    }
  }
}
AuthVerifyRequest

{
  "type": "object",
  "required": [
    "token"
  ],
  "properties": {
    "token": {
      "type": "string",
      "minLength": 1
    }
  }
}
AuthSession

schemas/AuthMeschemas/AuthMembership

{
  "type": "object",
  "required": [
    "access_token",
    "expires_at",
    "me"
  ],
  "properties": {
    "access_token": {
      "type": "string",
      "description": "Opaque rt_sess_ bearer."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    },
    "me": {
      "$ref": "#/components/schemas/AuthMe"
    },
    "memberships": {
      "type": "array",
      "description": "Every tenant the verified e-mail is a member of (REM-J tenant choice). Present only on the authVerify response; a single-tenant user gets a one-element list. The session is issued for `me.tenant`; choosing another membership re-verifies into that tenant.\n",
      "items": {
        "$ref": "#/components/schemas/AuthMembership"
      }
    },
    "tenant_choice_required": {
      "type": "boolean",
      "description": "True when memberships has more than one entry and the console must ask which tenant to enter before using the session. Never set by authMagicLink (enumerate-safe).\n"
    }
  }
}
AuthMembership

{
  "type": "object",
  "description": "One tenant membership of the verified user (REM-J).",
  "required": [
    "tenant_id",
    "tenant_name",
    "role"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "The tenant."
    },
    "tenant_name": {
      "type": "string",
      "description": "Display name of the tenant."
    },
    "tenant_slug": {
      "type": "string",
      "description": "Workspace slug for an explicitly tenant-bound magic-link request after email verification."
    },
    "role": {
      "type": "string",
      "description": "The user's role in that tenant (tenant_admin | tenant_editor | tenant_viewer | publisher | advertiser | ...)."
    }
  }
}
SessionsRevoked

{
  "type": "object",
  "required": [
    "revoked"
  ],
  "properties": {
    "revoked": {
      "type": "integer",
      "description": "Sessions ended, the caller's included."
    }
  }
}
AuthMe

schemas/Userschemas/Tenantschemas/Entitlement

{
  "type": "object",
  "required": [
    "operator",
    "roles"
  ],
  "properties": {
    "operator": {
      "type": "boolean"
    },
    "user": {
      "$ref": "#/components/schemas/User"
    },
    "tenant": {
      "$ref": "#/components/schemas/Tenant"
    },
    "roles": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "entitlements": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Entitlement"
      }
    }
  }
}
InviteStatus

{
  "type": "string",
  "enum": [
    "PENDING",
    "ACCEPTED",
    "EXPIRED",
    "REVOKED"
  ],
  "x-enum-varnames": [
    "InviteStatusPENDING",
    "InviteStatusACCEPTED",
    "InviteStatusEXPIRED",
    "InviteStatusREVOKED"
  ]
}
Invite

schemas/InviteStatus

{
  "type": "object",
  "description": "One invite challenge (auth_login_challenge purpose=invite) as seen by a tenant admin; the magic-link token is never returned.",
  "required": [
    "id",
    "tenant_id",
    "email",
    "role",
    "status",
    "created_at",
    "expires_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "role": {
      "type": "string"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Publisher binding for publisher-role invites (SR-1010)."
    },
    "status": {
      "$ref": "#/components/schemas/InviteStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    },
    "accepted_at": {
      "type": "string",
      "format": "date-time"
    },
    "revoked_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
InviteList

schemas/Invite

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Invite"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
InviteCreate

{
  "type": "object",
  "required": [
    "email",
    "role"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email"
    },
    "name": {
      "type": "string"
    },
    "role": {
      "type": "string",
      "enum": [
        "tenant_admin",
        "tenant_editor",
        "tenant_viewer",
        "advertiser",
        "publisher",
        "sales_rep",
        "campaign_manager",
        "creative_designer",
        "revenue_ops"
      ],
      "x-enum-varnames": [
        "InviteCreateRoleTenantAdmin",
        "InviteCreateRoleTenantEditor",
        "InviteCreateRoleTenantViewer",
        "InviteCreateRoleAdvertiser",
        "InviteCreateRolePublisher",
        "InviteCreateRoleSalesRep",
        "InviteCreateRoleCampaignManager",
        "InviteCreateRoleCreativeDesigner",
        "InviteCreateRoleRevenueOps"
      ]
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Required when role is publisher. The publisher must be non-archived in the same tenant at redemption. An existing invited user must already have this same non-null publisher binding; a missing or different binding returns 409 CONFLICT with a publisher_id field hint. Redemption never implicitly rebinds an existing user.\n"
    }
  }
}
StatusCounts

{
  "type": "object",
  "description": "Per-status row counts for a resource collection (console summary widgets) — the general status-counts operation from docs/spec/admin-api.md's resource conventions.\n",
  "required": [
    "counts"
  ],
  "properties": {
    "counts": {
      "type": "object",
      "additionalProperties": {
        "type": "integer",
        "format": "int64"
      },
      "description": "Map of status value (LifecycleStatus, or the resource's own status enum) to count."
    }
  }
}
DeliveryStatus

{
  "type": "string",
  "description": "riptide.common.v1.DeliveryStatus — the richer delivery lifecycle. Only ACTIVE serves; DRAFT/PAUSED/ENDED/ARCHIVED never serve (docs/spec/ad-server-delivery.md).\n",
  "enum": [
    "DRAFT",
    "ACTIVE",
    "PAUSED",
    "ENDED",
    "ARCHIVED"
  ]
}
CampaignOrder

schemas/DeliveryStatusschemas/FrequencyCapschemas/LifecycleStatusschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "description": "Booked order (advertiser, budget, dates, owners) — docs/design/02-data-model.md \"Ad server\" and docs/design/30-dsp-completeness.md. ref is auto-minted when omitted on create (P3-03 \"auto ref\"); advertiser_id is the owner constraint (NOT NULL, immutable after creation — validated to exist in-tenant on create); archiving an order cascades to archive every line item it owns (P3-03 \"status cascade\"). The delivery envelope is the serve-time order gate: a line item owned by an order serves only while the order is ACTIVE, inside the order flight (in the order's timezone), and under the order budgets — orders with defaulted delivery fields are an open gate (pre-existing behavior). currency is ISO 4217, immutable after create; line items inherit it. Cross-entity mismatches (line-item flight outside the order flight) surface as eligibility warnings, never silent drops.\n",
  "required": [
    "id",
    "tenant_id",
    "ref",
    "name",
    "advertiser_id",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "ref": {
      "type": "string",
      "description": "Short per-tenant reference code; auto-minted when omitted on create."
    },
    "name": {
      "type": "string"
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning advertiser (campaign_order.advertiser_id is NOT NULL, immutable)."
    },
    "delivery_status": {
      "$ref": "#/components/schemas/DeliveryStatus"
    },
    "start_at": {
      "type": "string",
      "format": "date-time",
      "description": "Order flight start (campaign_order.flight_start); omit for open start."
    },
    "end_at": {
      "type": "string",
      "format": "date-time",
      "description": "Order flight end (campaign_order.flight_end); omit for open end."
    },
    "timezone": {
      "type": "string",
      "description": "IANA timezone for the flight window and EVEN-pacing day fraction; spend/pacing counter day-buckets are UTC (design 31 §6). Defaults to UTC."
    },
    "currency": {
      "type": "string",
      "description": "ISO 4217 order currency; immutable after create. Line items inherit it."
    },
    "lifetime_budget": {
      "type": "string",
      "description": "Decimal money string (4dp), e.g. \"5000.0000\"; omit for uncapped."
    },
    "daily_budget": {
      "type": "string",
      "description": "Decimal money string (4dp); omit for uncapped."
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCap"
      },
      "description": "Order-level caps; most restrictive wins across association/line-item/order scopes."
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels (GC-03), additive to the advertiser's own labels for every line item this order owns. Arrays present on update replace the full set.\n"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "trafficker": {
      "type": "string",
      "description": "Person trafficking the order (SR-1011 commercial metadata)."
    },
    "agency": {
      "type": "string",
      "description": "Buying agency name."
    },
    "sales_owner": {
      "type": "string",
      "description": "Account / sales owner on the seller side."
    },
    "account_owner_user_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The app user who owns the account relationship (SR-1218): a user of the same tenant (references app_user). Null / omitted = unassigned; sales_owner stays the free-text seller-side name for commercial metadata.\n"
    },
    "po_number": {
      "type": "string",
      "description": "Purchase-order reference."
    },
    "notes": {
      "type": "string"
    },
    "billing_contact_name": {
      "type": "string"
    },
    "billing_contact_email": {
      "type": "string"
    },
    "monthly_goal_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "monthly_goal_budget": {
      "type": "string",
      "description": "Decimal money string (4 dp)."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
CampaignOrderCreate

schemas/SupplyTransparencyPolicyschemas/DeliveryStatusschemas/FrequencyCapInput

{
  "type": "object",
  "required": [
    "name",
    "advertiser_id"
  ],
  "properties": {
    "ref": {
      "type": "string",
      "minLength": 1,
      "description": "Auto-minted when omitted."
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "delivery_status": {
      "$ref": "#/components/schemas/DeliveryStatus"
    },
    "start_at": {
      "type": "string",
      "format": "date-time"
    },
    "end_at": {
      "type": "string",
      "format": "date-time"
    },
    "timezone": {
      "type": "string"
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3,
      "description": "ISO 4217; immutable after create (omit for USD)."
    },
    "lifetime_budget": {
      "type": "string"
    },
    "daily_budget": {
      "type": "string"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCapInput"
      }
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels (GC-03), additive to the advertiser's own labels for every line item this order owns. Arrays present on update replace the full set.\n"
    },
    "trafficker": {
      "type": "string",
      "description": "Person trafficking the order (SR-1011 commercial metadata)."
    },
    "agency": {
      "type": "string",
      "description": "Buying agency name."
    },
    "sales_owner": {
      "type": "string",
      "description": "Account / sales owner on the seller side."
    },
    "account_owner_user_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The app user who owns the account relationship (SR-1218): a user of the same tenant (references app_user). Null / omitted = unassigned; sales_owner stays the free-text seller-side name for commercial metadata.\n"
    },
    "po_number": {
      "type": "string",
      "description": "Purchase-order reference."
    },
    "notes": {
      "type": "string"
    },
    "billing_contact_name": {
      "type": "string"
    },
    "billing_contact_email": {
      "type": "string"
    },
    "monthly_goal_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "monthly_goal_budget": {
      "type": "string",
      "description": "Decimal money string (4 dp)."
    }
  }
}
CampaignOrderUpdate

schemas/SupplyTransparencyPolicyschemas/DeliveryStatusschemas/FrequencyCapInput

{
  "type": "object",
  "required": [
    "name"
  ],
  "description": "currency is immutable after create and intentionally absent here. Pausing or ending the order gates every owned line item at serve time (order gate); archiving cascades the archive to owned line items.\n",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "delivery_status": {
      "$ref": "#/components/schemas/DeliveryStatus"
    },
    "start_at": {
      "type": "string",
      "format": "date-time"
    },
    "end_at": {
      "type": "string",
      "format": "date-time"
    },
    "timezone": {
      "type": "string"
    },
    "lifetime_budget": {
      "type": "string"
    },
    "daily_budget": {
      "type": "string"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCapInput"
      }
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Competitive exclusion labels (GC-03), additive to the advertiser's own labels for every line item this order owns. Arrays present on update replace the full set.\n"
    },
    "trafficker": {
      "type": "string",
      "description": "Person trafficking the order (SR-1011 commercial metadata)."
    },
    "agency": {
      "type": "string",
      "description": "Buying agency name."
    },
    "sales_owner": {
      "type": "string",
      "description": "Account / sales owner on the seller side."
    },
    "account_owner_user_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The app user who owns the account relationship (SR-1218): a user of the same tenant (references app_user). Null / omitted = unassigned; sales_owner stays the free-text seller-side name for commercial metadata.\n"
    },
    "po_number": {
      "type": "string",
      "description": "Purchase-order reference."
    },
    "notes": {
      "type": "string"
    },
    "billing_contact_name": {
      "type": "string"
    },
    "billing_contact_email": {
      "type": "string"
    },
    "monthly_goal_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "monthly_goal_budget": {
      "type": "string",
      "description": "Decimal money string (4 dp)."
    }
  }
}
CampaignOrderDuplicateRequest

{
  "type": "object",
  "required": [
    "name"
  ],
  "description": "Body for duplicateCampaignOrder. Deep copy: line items and their weighted-creative associations are copied (creatives referenced, not copied), refs are freshly auto-minted, delivery statuses reset to DRAFT, and delivery counters start at zero.\n",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "Name for the new order."
    },
    "include_line_items": {
      "type": "boolean",
      "default": true,
      "description": "Copy owned line items + associations; false copies the order shell only."
    }
  }
}
CampaignOrderList

schemas/CampaignOrder

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CampaignOrder"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
LineItemKind

{
  "type": "string",
  "description": "DIRECT (booked/guaranteed) or HOUSE (no-cost filler).",
  "enum": [
    "DIRECT",
    "HOUSE"
  ]
}
PacingMode

{
  "type": "string",
  "enum": [
    "EVEN",
    "ASAP",
    "MANUAL_WEIGHT"
  ]
}
PriorityClass

{
  "type": "string",
  "enum": [
    "SPONSORSHIP",
    "STANDARD",
    "HOUSE",
    "BACKFILL"
  ]
}
DeliveryGoalType

{
  "type": "string",
  "description": "riptide.common.v1.DeliveryGoalType — what lifetime/daily goals count. CONVERSIONS / REVENUE / SHARE_OF_VOICE are buyer-parity multi-metric goals (design 32 §4.4).\n",
  "enum": [
    "IMPRESSIONS",
    "COMPLETIONS",
    "CLICKS",
    "SPEND",
    "CONVERSIONS",
    "REVENUE",
    "SHARE_OF_VOICE"
  ]
}
DemandRateType

{
  "type": "string",
  "description": "riptide.common.v1.DemandRateType — advertiser buy-rate model on a line item. Distinct from supply PricingType. Non-CPM values require tenant entitlement `demand_rate_types`.\n",
  "enum": [
    "CPM",
    "CPC",
    "CPA",
    "FLAT"
  ]
}
BiddingStrategy

{
  "type": "string",
  "description": "riptide.common.v1.BiddingStrategy — optimization target. VCR optimizes toward video completion rate under a max CPM (deterministic baseline + Decisioner override).\n",
  "enum": [
    "CPM",
    "CPC",
    "CPA",
    "VCR"
  ]
}
OptimizationGoal

{
  "type": "string",
  "description": "riptide.common.v1.OptimizationGoal — ROAS/GMV autobid objective (design 35 §6 / CP-13). NONE leaves the base bid unchanged. ROAS/GMV require tenant entitlement `roas_autobid`. Optimization revenue/GMV feeds the bid Decisioner only; platform meter is unchanged.\n",
  "enum": [
    "NONE",
    "ROAS",
    "GMV"
  ]
}
FreqCapNoKeyPolicy

{
  "type": "string",
  "description": "riptide.common.v1.FreqCapNoKeyPolicy — behavior when a request carries no user key for frequency capping. SERVE keeps the fail-open behavior (caps skipped without a key); SKIP drops the line item from the candidate set instead.\n",
  "enum": [
    "SERVE",
    "SKIP"
  ]
}
HourlyShape

{
  "type": "string",
  "enum": [
    "OFF",
    "LEVEL",
    "ACCELERATED"
  ],
  "x-enum-varnames": [
    "HourlyShapeOFF",
    "HourlyShapeLEVEL",
    "HourlyShapeACCELERATED"
  ],
  "description": "Hourly shaping of the remaining goal (docs/design/31-dsp-completeness.md \"Pacing parity\"): LEVEL spreads the remaining goal over the scheduled hours with a 1.05 catch-up factor, ACCELERATED with 1.40; the hourly weight max((hourly goal − delivered this hour) ÷ priority, 0) weights selection and a met hourly goal withholds the line item for the rest of the hour. OFF (default) disables hourly shaping.\n"
}
LineItemDeliveryState

{
  "type": "object",
  "required": [
    "line_item_id",
    "state",
    "eligible_to_bid",
    "delivered",
    "remaining",
    "spend",
    "computed_at",
    "counters_available"
  ],
  "description": "Server-computed delivery state of a line item over the live pacing counters (design 31 \"Pacing parity\" / SR-1202): PENDING, SERVING, GOAL_REACHED, FLIGHT_ENDED or INACTIVE (the pacing_state vocabulary), derived by the same pure gates the serving engine runs. counters_available=false means the hot store is not configured and every counter reads zero (reported honestly, never guessed).\n",
  "properties": {
    "line_item_id": {
      "type": "string",
      "format": "uuid"
    },
    "state": {
      "type": "string",
      "enum": [
        "PENDING",
        "SERVING",
        "GOAL_REACHED",
        "FLIGHT_ENDED",
        "INACTIVE"
      ],
      "x-enum-varnames": [
        "LineItemDeliveryStateStatePENDING",
        "LineItemDeliveryStateStateSERVING",
        "LineItemDeliveryStateStateGOALREACHED",
        "LineItemDeliveryStateStateFLIGHTENDED",
        "LineItemDeliveryStateStateINACTIVE"
      ],
      "description": "One of PENDING | SERVING | GOAL_REACHED | FLIGHT_ENDED | INACTIVE (libs/auction/direct.DeliveryState)."
    },
    "eligible_to_bid": {
      "type": "boolean",
      "description": "True when the line item would bid right now."
    },
    "lifetime_goal_effective": {
      "type": "integer",
      "format": "int64",
      "description": "Lifetime goal with the delivery buffer applied."
    },
    "daily_goal_effective": {
      "type": "integer",
      "format": "int64"
    },
    "delivered": {
      "type": "integer",
      "format": "int64"
    },
    "daily_delivered": {
      "type": "integer",
      "format": "int64"
    },
    "remaining": {
      "type": "integer",
      "format": "int64"
    },
    "spend": {
      "type": "string",
      "description": "Booked spend so far (money decimal, 4 dp) in the order currency."
    },
    "hourly_shaping": {
      "type": "boolean"
    },
    "hourly_goal": {
      "type": "integer",
      "format": "int64"
    },
    "hourly_weight": {
      "type": "number",
      "format": "double",
      "description": "Hourly shaping weight max((hourly goal − delivered this hour) ÷ priority, 0)."
    },
    "bid_rate_cap": {
      "type": "integer",
      "format": "int64",
      "description": "Render-rate bid budget left this hour (when hourly shaping applies)."
    },
    "render_throttled": {
      "type": "boolean"
    },
    "dynamic_pricing": {
      "type": "boolean",
      "description": "True when the line item bids the dynamic eCPM (budget + goal)."
    },
    "dynamic_ecpm": {
      "type": "string",
      "description": "The dynamic eCPM it bids with now (money decimal)."
    },
    "counters_available": {
      "type": "boolean"
    },
    "computed_at": {
      "type": "string",
      "format": "date-time"
    },
    "pacing_state": {
      "type": "string",
      "enum": [
        "ON_TRACK",
        "GOAL_REACHED",
        "FLIGHT_ENDED"
      ],
      "x-enum-varnames": [
        "LineItemDeliveryStatePacingStateONTRACK",
        "LineItemDeliveryStatePacingStateGOALREACHED",
        "LineItemDeliveryStatePacingStateFLIGHTENDED"
      ],
      "description": "The pacer's control-plane projection of the state (SR-1202; libs/auction/direct PacingStateFor): ON_TRACK while under goals and budgets (PENDING / SERVING / INACTIVE), GOAL_REACHED at a goal or budget hard stop, FLIGHT_ENDED once the flight end has passed or the line item is ENDED / ARCHIVED. The pacing cycle (services/console pacing_tick.go) writes the same value — with the effective goals, delivered count, hourly goal and bid-rate cap — to the line item of record (line_item.pacing_state, migration 0103) every minute, so this read and the stored projection can only ever differ by one cycle.\n"
    }
  }
}
LineItem

schemas/LineItemKindschemas/DemandRateTypeschemas/BiddingStrategyschemas/OptimizationGoalschemas/PacingModeschemas/DeliveryGoalTypeschemas/PriorityClassschemas/HourlyShapeschemas/FreqCapNoKeyPolicyschemas/FrequencyCapschemas/WeightedCreativeRefschemas/Daypartschemas/LineItemFlightschemas/SupplyTransparencyPolicyschemas/LifecycleStatusschemas/DeliveryStatus

{
  "type": "object",
  "description": "Deliverable within a campaign order — docs/design/02-data-model.md \"Ad server\". kind is immutable after creation; ref/audience auto-mint on create. Full delivery surface (pacing/goals/budgets/caps/creatives/dayparts) is admin-editable (RIP-133).\n",
  "required": [
    "id",
    "tenant_id",
    "ref",
    "name",
    "kind",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "campaign_order_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning campaign order, if any."
    },
    "ref": {
      "type": "string",
      "description": "Short per-tenant reference code; auto-minted when omitted on create."
    },
    "name": {
      "type": "string"
    },
    "kind": {
      "$ref": "#/components/schemas/LineItemKind"
    },
    "cpm": {
      "type": "string",
      "description": "Decimal CPM (4dp string), e.g. \"8.5000\". Legacy alias when demand_rate_type=CPM."
    },
    "demand_rate_type": {
      "$ref": "#/components/schemas/DemandRateType"
    },
    "rate_amount": {
      "type": "string",
      "description": "Buy rate in order currency (4dp decimal string). Required for non-CPM demand rates when entitlement demand_rate_types is on."
    },
    "bidding_strategy": {
      "$ref": "#/components/schemas/BiddingStrategy"
    },
    "bid_modifier_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "Optional tenant bid modifier applied after base bid, before predicted eCPM."
    },
    "optimization_goal": {
      "$ref": "#/components/schemas/OptimizationGoal"
    },
    "target_roas": {
      "type": "string",
      "description": "Autobid target as a 4dp decimal string (e.g. \"2.5000\"). Required when optimization_goal is ROAS or GMV (design 35 §6 autobid_target).\n"
    },
    "max_cpm": {
      "type": "string",
      "description": "Hard autobid CPM cap as a 4dp decimal string (design 35 §6 autobid_max_cpm). Distinct from the line item's base `cpm` / rate_amount.\n"
    },
    "priority": {
      "type": "integer"
    },
    "pacing_mode": {
      "$ref": "#/components/schemas/PacingMode"
    },
    "pacing_weight": {
      "type": "number"
    },
    "goal_type": {
      "$ref": "#/components/schemas/DeliveryGoalType"
    },
    "lifetime_goal": {
      "type": "integer",
      "format": "int64"
    },
    "daily_goal": {
      "type": "integer",
      "format": "int64"
    },
    "lifetime_budget": {
      "type": "string"
    },
    "daily_budget": {
      "type": "string"
    },
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "guaranteed": {
      "type": "boolean"
    },
    "timezone": {
      "type": "string",
      "description": "IANA timezone for daypart/flight evaluation."
    },
    "pacing_tolerance_pct": {
      "type": "string",
      "description": "EVEN-pacing soft-throttle tolerance as a decimal percent string in 0-100 (e.g. \"12.500000\"). Omit for the engine default (10).\n"
    },
    "goal_buffer_pct": {
      "type": "string",
      "description": "Delivery buffer as a decimal percent string 0-100 (e.g. \"5.000000\"): the pacer delivers against goal × (1 + buffer/100) so the booked goal is met after discrepancy (docs/design/31-dsp-completeness.md \"Pacing parity\"). Empty = no buffer.\n"
    },
    "hourly_shape": {
      "$ref": "#/components/schemas/HourlyShape"
    },
    "freq_cap_no_key": {
      "$ref": "#/components/schemas/FreqCapNoKeyPolicy"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCap"
      }
    },
    "advertiser_domain": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Line-item scope competitive exclusion labels (GC-03). Serving enforces the union of advertiser + campaign order + line item labels; this field carries only the labels declared directly on the line item. Arrays present on update replace the full set.\n"
    },
    "creatives": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WeightedCreativeRef"
      }
    },
    "dayparts": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Daypart"
      }
    },
    "flights": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/LineItemFlight"
      },
      "description": "Sequential budget segments (GC-05, design 32 §10), sorted by sequence. Empty means legacy behavior: the whole line-item window is one implicit flight. On update the array is upserted by id, not replaced — see LineItemUpdate.flights.\n"
    },
    "ip_block_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Tenant IP lists in block mode (ADR D36). Request IP matching any list excludes this line item (`ip_blocked`).\n"
    },
    "ip_allow_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Tenant IP lists in allow mode (ADR D36). When set, request IP must be a member of every listed allow set or the line item is excluded (`ip_not_allowed`).\n"
    },
    "custom_block_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Tenant custom lists in block mode (design 32 §6.1). Matching kind membership excludes this line item.\n"
    },
    "custom_allow_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Tenant custom lists in allow mode (design 32 §6.1). When set, the request must match every listed allow set or the line item is excluded.\n"
    },
    "catalog_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "Optional item catalog (design 35 / CP-6) this line item draws sponsored-product candidates from. Distinct from MarketplaceListing. Null/omit = not a listing LI.\n"
    },
    "catalog_external_item_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "External item ids (SKU keys) eligible under catalog_id. Empty with catalog_id set means all available catalog items may compete.\n"
    },
    "relevancy_weight": {
      "type": "integer",
      "format": "int64",
      "description": "Listing composite-score weight (design 35). predicted_ecpm * max(1, weight) + relevancy. Omit or 0 treated as 1 by libs/catalog.Rank.\n"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid",
      "description": "Targeting audience; auto-created and auto-named when omitted on create."
    },
    "start_at": {
      "type": "string",
      "format": "date-time",
      "description": "Flight window start (line_item.flight_start)."
    },
    "end_at": {
      "type": "string",
      "format": "date-time",
      "description": "Flight window end (line_item.flight_end)."
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "delivery_status": {
      "$ref": "#/components/schemas/DeliveryStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
LineItemCreate

schemas/LineItemKindschemas/DemandRateTypeschemas/BiddingStrategyschemas/OptimizationGoalschemas/PacingModeschemas/DeliveryGoalTypeschemas/PriorityClassschemas/HourlyShapeschemas/FreqCapNoKeyPolicyschemas/FrequencyCapInputschemas/WeightedCreativeRefschemas/Daypartschemas/LineItemFlightschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "required": [
    "name",
    "kind"
  ],
  "properties": {
    "campaign_order_id": {
      "type": "string",
      "format": "uuid"
    },
    "ref": {
      "type": "string",
      "minLength": 1,
      "description": "Auto-minted when omitted."
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "kind": {
      "$ref": "#/components/schemas/LineItemKind"
    },
    "cpm": {
      "type": "string"
    },
    "demand_rate_type": {
      "$ref": "#/components/schemas/DemandRateType"
    },
    "rate_amount": {
      "type": "string"
    },
    "bidding_strategy": {
      "$ref": "#/components/schemas/BiddingStrategy"
    },
    "bid_modifier_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "optimization_goal": {
      "$ref": "#/components/schemas/OptimizationGoal"
    },
    "target_roas": {
      "type": "string"
    },
    "max_cpm": {
      "type": "string"
    },
    "priority": {
      "type": "integer"
    },
    "pacing_mode": {
      "$ref": "#/components/schemas/PacingMode"
    },
    "pacing_weight": {
      "type": "number"
    },
    "goal_type": {
      "$ref": "#/components/schemas/DeliveryGoalType"
    },
    "lifetime_goal": {
      "type": "integer",
      "format": "int64"
    },
    "daily_goal": {
      "type": "integer",
      "format": "int64"
    },
    "lifetime_budget": {
      "type": "string"
    },
    "daily_budget": {
      "type": "string"
    },
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "guaranteed": {
      "type": "boolean"
    },
    "timezone": {
      "type": "string"
    },
    "pacing_tolerance_pct": {
      "type": "string",
      "description": "Decimal percent string 0-100; omit for the engine default (10)."
    },
    "goal_buffer_pct": {
      "type": "string",
      "description": "Delivery buffer percent 0-100; see LineItem.goal_buffer_pct."
    },
    "hourly_shape": {
      "$ref": "#/components/schemas/HourlyShape"
    },
    "freq_cap_no_key": {
      "$ref": "#/components/schemas/FreqCapNoKeyPolicy"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCapInput"
      }
    },
    "advertiser_domain": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Line-item scope competitive exclusion labels (GC-03). Serving enforces the union of advertiser + campaign order + line item labels; this field carries only the labels declared directly on the line item. Arrays present on update replace the full set.\n"
    },
    "creatives": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WeightedCreativeRef"
      }
    },
    "dayparts": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Daypart"
      }
    },
    "flights": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/LineItemFlight"
      },
      "description": "Sequential, non-overlapping budget segments (GC-05, design 32 §10). Omit ids — the server mints them and derives sequence from start_at order. Empty/omitted means legacy behavior (whole line-item window is one implicit flight).\n"
    },
    "ip_block_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Published tenant IP lists with mode=block."
    },
    "ip_allow_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Published tenant IP lists with mode=allow."
    },
    "custom_block_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "custom_allow_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "catalog_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "catalog_external_item_ids": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "relevancy_weight": {
      "type": "integer",
      "format": "int64"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid",
      "description": "Omit to auto-create an auto-named audience for this line item."
    },
    "start_at": {
      "type": "string",
      "format": "date-time"
    },
    "end_at": {
      "type": "string",
      "format": "date-time"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    }
  }
}
LineItemUpdate

schemas/DemandRateTypeschemas/BiddingStrategyschemas/OptimizationGoalschemas/PacingModeschemas/DeliveryGoalTypeschemas/PriorityClassschemas/HourlyShapeschemas/FreqCapNoKeyPolicyschemas/FrequencyCapInputschemas/WeightedCreativeRefschemas/Daypartschemas/LineItemFlightschemas/SupplyTransparencyPolicy

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "cpm": {
      "type": "string"
    },
    "demand_rate_type": {
      "$ref": "#/components/schemas/DemandRateType"
    },
    "rate_amount": {
      "type": "string"
    },
    "bidding_strategy": {
      "$ref": "#/components/schemas/BiddingStrategy"
    },
    "bid_modifier_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "optimization_goal": {
      "$ref": "#/components/schemas/OptimizationGoal"
    },
    "target_roas": {
      "type": "string"
    },
    "max_cpm": {
      "type": "string"
    },
    "priority": {
      "type": "integer"
    },
    "pacing_mode": {
      "$ref": "#/components/schemas/PacingMode"
    },
    "pacing_weight": {
      "type": "number"
    },
    "goal_type": {
      "$ref": "#/components/schemas/DeliveryGoalType"
    },
    "lifetime_goal": {
      "type": "integer",
      "format": "int64"
    },
    "daily_goal": {
      "type": "integer",
      "format": "int64"
    },
    "lifetime_budget": {
      "type": "string"
    },
    "daily_budget": {
      "type": "string"
    },
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "guaranteed": {
      "type": "boolean"
    },
    "timezone": {
      "type": "string"
    },
    "start_at": {
      "type": "string",
      "format": "date-time",
      "description": "Flight window start (line_item.flight_start); omit to leave unchanged."
    },
    "end_at": {
      "type": "string",
      "format": "date-time",
      "description": "Flight window end (line_item.flight_end); omit to leave unchanged."
    },
    "pacing_tolerance_pct": {
      "type": "string",
      "description": "Decimal percent string 0-100; omit for the engine default (10)."
    },
    "goal_buffer_pct": {
      "type": "string",
      "description": "Delivery buffer percent 0-100; see LineItem.goal_buffer_pct."
    },
    "hourly_shape": {
      "$ref": "#/components/schemas/HourlyShape"
    },
    "freq_cap_no_key": {
      "$ref": "#/components/schemas/FreqCapNoKeyPolicy"
    },
    "frequency_caps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/FrequencyCapInput"
      }
    },
    "advertiser_domain": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "exclusion_labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128
      },
      "description": "Line-item scope competitive exclusion labels (GC-03). Serving enforces the union of advertiser + campaign order + line item labels; this field carries only the labels declared directly on the line item. Arrays present on update replace the full set.\n"
    },
    "creatives": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WeightedCreativeRef"
      }
    },
    "dayparts": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Daypart"
      }
    },
    "flights": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/LineItemFlight"
      },
      "description": "Sequential, non-overlapping budget segments (GC-05, design 32 §10). When present the array is upserted by id (not plain-replaced, because flight identity keys delivery counters): entries carrying a known id UPDATE that flight in place preserving its identity and delivered counters; existing flights whose id is absent from the payload are DELETED; entries without id INSERT as new flights. Omit the field to leave flights unchanged; send [] to delete all flights.\n"
    },
    "ip_block_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Replaces the line item's block-list bindings when present."
    },
    "ip_allow_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Replaces the line item's allow-list bindings when present."
    },
    "custom_block_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Replaces the line item's custom block-list bindings when present."
    },
    "custom_allow_list_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      },
      "description": "Replaces the line item's custom allow-list bindings when present."
    },
    "catalog_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "catalog_external_item_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Replaces the line item's catalog SKU keys when present."
    },
    "relevancy_weight": {
      "type": "integer",
      "format": "int64"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "supply_transparency": {
      "$ref": "#/components/schemas/SupplyTransparencyPolicy"
    }
  }
}
LineItemPeriod

{
  "type": "object",
  "description": "The new flight window for extendLineItem's replacement line item.",
  "properties": {
    "start_at": {
      "type": "string",
      "format": "date-time"
    },
    "end_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
LineItemList

schemas/LineItem

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/LineItem"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
EligibilityConditionSeverity

{
  "type": "string",
  "description": "BLOCKING conditions stop serving; WARNING conditions do not stop serving but signal likely misconfiguration (e.g. line-item flight outside the order flight); INFO reports honest unknowns (e.g. COUNTERS_UNAVAILABLE) and context.\n",
  "enum": [
    "BLOCKING",
    "WARNING",
    "INFO"
  ]
}
EligibilityCondition

schemas/EligibilityConditionSeverityschemas/BudgetMode

{
  "type": "object",
  "required": [
    "code",
    "severity",
    "message"
  ],
  "description": "One condition from the serve engine's own eligibility functions (design 30 §2H). code is a stable machine-readable identifier (e.g. order_not_active, flight_not_started, no_servable_creative, budget_exhausted, COUNTERS_UNAVAILABLE); entity/entity_id name the entity the condition was evaluated on (line_item, campaign_order, creative, ...).\n",
  "properties": {
    "code": {
      "type": "string"
    },
    "severity": {
      "$ref": "#/components/schemas/EligibilityConditionSeverity"
    },
    "message": {
      "type": "string",
      "description": "Human-readable explanation of the condition."
    },
    "entity": {
      "type": "string",
      "description": "Entity type the condition applies to (line_item, campaign_order, creative, ...)."
    },
    "entity_id": {
      "type": "string",
      "description": "Id of the entity the condition applies to."
    },
    "budget_mode": {
      "$ref": "#/components/schemas/BudgetMode"
    }
  }
}
EligibilityReport

schemas/EligibilityConditionschemas/BudgetMode

{
  "type": "object",
  "required": [
    "serving",
    "conditions"
  ],
  "description": "Deterministic servability report for a line item, computed by the same pure functions the serve engine runs — order gate, flight, dayparts, approvals, associations, and (where the counter store is reachable) budgets/pacing/caps. Counter-dependent checks report COUNTERS_UNAVAILABLE (INFO) when the counter store is not configured. serving is true iff no BLOCKING condition is present.\n",
  "properties": {
    "serving": {
      "type": "boolean"
    },
    "conditions": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/EligibilityCondition"
      }
    },
    "budget_mode": {
      "$ref": "#/components/schemas/BudgetMode"
    }
  }
}
BudgetMode

{
  "type": "string",
  "nullable": true,
  "description": "How a line item's budget is admitted across cells (SR-1223, riptide.budget.v1.BudgetMode): LOCAL_ALLOWANCE (the settler's per-cell allowance), TOKEN_BLOCK (near-goal token blocks), LOCAL_EVEN (no allowance yet — even split by the tenant's cell weights). Null when the line item has no money goal or budgets were not evaluated.\n",
  "enum": [
    "LOCAL_ALLOWANCE",
    "TOKEN_BLOCK",
    "LOCAL_EVEN"
  ],
  "x-enum-varnames": [
    "BudgetModeLOCALALLOWANCE",
    "BudgetModeTOKENBLOCK",
    "BudgetModeLOCALEVEN"
  ]
}
LineItemBulkStatusAction

{
  "type": "string",
  "description": "Delivery-status transition to apply (DeliveryStatus target ACTIVE|PAUSED|ARCHIVED).",
  "enum": [
    "ACTIVATE",
    "PAUSE",
    "ARCHIVE"
  ]
}
LineItemBulkStatusRequest

schemas/LineItemBulkStatusAction

{
  "type": "object",
  "required": [
    "ids",
    "status"
  ],
  "properties": {
    "ids": {
      "type": "array",
      "minItems": 1,
      "maxItems": 100,
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "status": {
      "$ref": "#/components/schemas/LineItemBulkStatusAction"
    }
  }
}
LineItemBulkStatusItemResult

{
  "type": "object",
  "required": [
    "id",
    "ok"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "ok": {
      "type": "boolean"
    },
    "error_code": {
      "type": "string",
      "description": "Stable machine-readable code when ok=false (e.g. not_found, no_servable_creative)."
    },
    "error_message": {
      "type": "string",
      "description": "Human-readable explanation when ok=false."
    }
  }
}
LineItemBulkStatusResult

schemas/LineItemBulkStatusItemResult

{
  "type": "object",
  "required": [
    "results"
  ],
  "description": "Multi-status result (design 30 §2I): one entry per requested id, in request order — never all-or-nothing, never a silent partial failure.\n",
  "properties": {
    "results": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/LineItemBulkStatusItemResult"
      }
    }
  }
}
CreativeKind

{
  "type": "string",
  "description": "Creative media kind (design 30 §2D). VAST and MEDIA are legacy kinds accepted for compatibility and normalized to VIDEO by the platform (riptide.common.v1.CreativeKind); DISPLAY/VIDEO/AUDIO/NATIVE map 1:1 to the normalized enum.\n",
  "enum": [
    "VAST",
    "MEDIA",
    "DISPLAY",
    "VIDEO",
    "AUDIO",
    "NATIVE"
  ]
}
CreativePipelineStatus

{
  "type": "string",
  "description": "upload→store→watermark→transcode→ready (P3-03); advanced one step at a time via POST .../creatives/{id}/pipeline/advance.\n",
  "enum": [
    "UPLOADED",
    "STORED",
    "WATERMARKED",
    "TRANSCODED",
    "READY"
  ]
}
CreativeApprovalStatus

{
  "type": "string",
  "description": "Compliance review gate; auto-approved on reaching READY when still PENDING (P3-03).",
  "enum": [
    "PENDING",
    "APPROVED",
    "REJECTED"
  ]
}
Creative

schemas/CreativeKindschemas/EntityVerificationschemas/ProximityTargetschemas/CompanionSlotschemas/InteractiveCreativeFileschemas/CreativePipelineStatusschemas/CreativeApprovalStatusschemas/LifecycleStatus

{
  "type": "object",
  "description": "VAST tag / hosted media / display / native creative — docs/design/02-data-model.md \"Ad server\" and docs/design/30-dsp-completeness.md. pipeline_status/approval_status and the review audit fields (approval_reason/approval_feedback/reviewed_at/reviewed_by) are read-only (advanced via pipeline/advance and the review endpoint). Content, measurement, and proximity fields are admin-editable (RIP-133). When the tenant's creative_auto_approve is off, a material content change (markup, click, media) resets APPROVED → PENDING.\n",
  "required": [
    "id",
    "tenant_id",
    "ref",
    "name",
    "kind",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "ref": {
      "type": "string",
      "description": "Short per-tenant reference code."
    },
    "name": {
      "type": "string"
    },
    "kind": {
      "$ref": "#/components/schemas/CreativeKind"
    },
    "vast_url": {
      "type": "string"
    },
    "vast_xml": {
      "type": "string"
    },
    "duration": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "click_url": {
      "type": "string"
    },
    "width": {
      "type": "integer",
      "minimum": 0,
      "description": "Creative width in pixels (display/native slot fitting); 0 = unset."
    },
    "height": {
      "type": "integer",
      "minimum": 0,
      "description": "Creative height in pixels; 0 = unset."
    },
    "markup": {
      "type": "string",
      "description": "Display HTML/tag markup; empty for hosted-image/video creatives."
    },
    "native_payload": {
      "type": "string",
      "description": "OpenRTB Native 1.2 response JSON document (string); empty = none."
    },
    "adomain": {
      "type": "string",
      "description": "Advertiser domain carried into bid responses and blocklist checks."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "Hard serving stop after expiry; omit for no expiry."
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "proximity": {
      "$ref": "#/components/schemas/ProximityTarget"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "template_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "Optional creative template (design 32 §6.2); render expands markup_template."
    },
    "template_fields": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Field values substituted into the template's {{MACRO}} tokens."
    },
    "companions": {
      "type": "array",
      "maxItems": 8,
      "items": {
        "$ref": "#/components/schemas/CompanionSlot"
      },
      "description": "Companion ads rendered alongside the primary creative (VAST 4.x Companion; SR-1211). Each slot is filled into a placement companion_slots entry of the same size. Arrays present on update replace the full set.\n"
    },
    "native_privacy_url": {
      "type": "string",
      "format": "uri",
      "maxLength": 2048,
      "nullable": true,
      "description": "HTTPS privacy-policy URL for native creatives (REM-G / SR-1239b): fills the Native response `privacy` field when the buyer payload lacks one. Null = none.\n"
    },
    "interactive_file": {
      "nullable": true,
      "description": "Interactive layer of a video creative (SR-1211). On update, omitted = unchanged and an explicit null clears it (the DemandPartner nullable-clears rule).",
      "allOf": [
        {
          "$ref": "#/components/schemas/InteractiveCreativeFile"
        }
      ]
    },
    "pipeline_status": {
      "$ref": "#/components/schemas/CreativePipelineStatus"
    },
    "approval_status": {
      "$ref": "#/components/schemas/CreativeApprovalStatus"
    },
    "approval_reason": {
      "type": "string",
      "readOnly": true,
      "description": "Machine-readable review reason code (set via reviewCreative)."
    },
    "approval_feedback": {
      "type": "string",
      "readOnly": true,
      "description": "Reviewer free-text feedback (set via reviewCreative)."
    },
    "reviewed_at": {
      "type": "string",
      "format": "date-time",
      "readOnly": true
    },
    "reviewed_by": {
      "type": "string",
      "readOnly": true,
      "description": "Actor label of the reviewer."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
CreativeCreate

schemas/CreativeKindschemas/EntityVerificationschemas/ProximityTargetschemas/CompanionSlotschemas/InteractiveCreativeFile

{
  "type": "object",
  "required": [
    "ref",
    "name",
    "kind"
  ],
  "properties": {
    "ref": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "kind": {
      "$ref": "#/components/schemas/CreativeKind"
    },
    "vast_url": {
      "type": "string"
    },
    "vast_xml": {
      "type": "string"
    },
    "duration": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "click_url": {
      "type": "string"
    },
    "width": {
      "type": "integer",
      "minimum": 0
    },
    "height": {
      "type": "integer",
      "minimum": 0
    },
    "markup": {
      "type": "string"
    },
    "native_payload": {
      "type": "string",
      "description": "OpenRTB Native 1.2 response JSON document (string)."
    },
    "adomain": {
      "type": "string"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "proximity": {
      "$ref": "#/components/schemas/ProximityTarget"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "template_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "template_fields": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "companions": {
      "type": "array",
      "maxItems": 8,
      "items": {
        "$ref": "#/components/schemas/CompanionSlot"
      },
      "description": "Companion ads rendered alongside the primary creative (VAST 4.x Companion; SR-1211). Each slot is filled into a placement companion_slots entry of the same size. Arrays present on update replace the full set.\n"
    },
    "native_privacy_url": {
      "type": "string",
      "format": "uri",
      "maxLength": 2048,
      "nullable": true,
      "description": "HTTPS privacy-policy URL for native creatives (REM-G / SR-1239b): fills the Native response `privacy` field when the buyer payload lacks one. Null = none.\n"
    },
    "interactive_file": {
      "nullable": true,
      "description": "Interactive layer of a video creative (SR-1211). On update, omitted = unchanged and an explicit null clears it (the DemandPartner nullable-clears rule).",
      "allOf": [
        {
          "$ref": "#/components/schemas/InteractiveCreativeFile"
        }
      ]
    }
  }
}
CreativeUpdate

schemas/EntityVerificationschemas/ProximityTargetschemas/CompanionSlotschemas/InteractiveCreativeFile

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "vast_url": {
      "type": "string"
    },
    "vast_xml": {
      "type": "string"
    },
    "duration": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "click_url": {
      "type": "string"
    },
    "width": {
      "type": "integer",
      "minimum": 0
    },
    "height": {
      "type": "integer",
      "minimum": 0
    },
    "markup": {
      "type": "string"
    },
    "native_payload": {
      "type": "string",
      "description": "OpenRTB Native 1.2 response JSON document (string)."
    },
    "adomain": {
      "type": "string"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    },
    "verification": {
      "$ref": "#/components/schemas/EntityVerification"
    },
    "proximity": {
      "$ref": "#/components/schemas/ProximityTarget"
    },
    "audience_id": {
      "type": "string",
      "format": "uuid"
    },
    "template_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "template_fields": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "companions": {
      "type": "array",
      "maxItems": 8,
      "items": {
        "$ref": "#/components/schemas/CompanionSlot"
      },
      "description": "Companion ads rendered alongside the primary creative (VAST 4.x Companion; SR-1211). Each slot is filled into a placement companion_slots entry of the same size. Arrays present on update replace the full set.\n"
    },
    "native_privacy_url": {
      "type": "string",
      "format": "uri",
      "maxLength": 2048,
      "nullable": true,
      "description": "HTTPS privacy-policy URL for native creatives (REM-G / SR-1239b): fills the Native response `privacy` field when the buyer payload lacks one. Null = none.\n"
    },
    "interactive_file": {
      "nullable": true,
      "description": "Interactive layer of a video creative (SR-1211). On update, omitted = unchanged and an explicit null clears it (the DemandPartner nullable-clears rule).",
      "allOf": [
        {
          "$ref": "#/components/schemas/InteractiveCreativeFile"
        }
      ]
    }
  }
}
CompanionSlotTrackers

{
  "type": "object",
  "description": "Third-party trackers for one companion slot (SR-1211); every URL is HTTPS and macro-templated.",
  "properties": {
    "creative_view": {
      "type": "array",
      "maxItems": 16,
      "items": {
        "type": "string",
        "maxLength": 2048
      },
      "description": "Fired when the companion is rendered (VAST creativeView)."
    },
    "click": {
      "type": "array",
      "maxItems": 16,
      "items": {
        "type": "string",
        "maxLength": 2048
      },
      "description": "Fired on companion click (VAST CompanionClickTracking)."
    }
  }
}
CompanionSlot

schemas/CompanionSlotTrackers

{
  "type": "object",
  "description": "One companion ad carried by a creative (VAST 4.x Companion; SR-1211): exactly one of static_url (image), html (HTMLResource), or iframe_url (IFrameResource) is the resource.\n",
  "required": [
    "width",
    "height"
  ],
  "properties": {
    "id": {
      "type": "string",
      "maxLength": 64,
      "description": "Stable slot id within the creative (rendered as the Companion id); minted when omitted."
    },
    "width": {
      "type": "integer",
      "minimum": 1,
      "description": "Companion width in pixels."
    },
    "height": {
      "type": "integer",
      "minimum": 1,
      "description": "Companion height in pixels."
    },
    "static_url": {
      "type": "string",
      "maxLength": 2048,
      "description": "HTTPS image resource (StaticResource) when the companion is an image."
    },
    "html": {
      "type": "string",
      "maxLength": 65536,
      "description": "Inline HTML resource (HTMLResource) when the companion is markup."
    },
    "iframe_url": {
      "type": "string",
      "maxLength": 2048,
      "description": "HTTPS iframe resource (IFrameResource) when the companion is a hosted page."
    },
    "click_url": {
      "type": "string",
      "maxLength": 2048,
      "description": "Companion click-through (CompanionClickThrough); omit to inherit the creative's click_url."
    },
    "alt_text": {
      "type": "string",
      "maxLength": 256,
      "description": "Alternative text (AltText) for image companions."
    },
    "trackers": {
      "$ref": "#/components/schemas/CompanionSlotTrackers"
    }
  }
}
InteractiveApiFramework

{
  "type": "string",
  "description": "Interactive creative API the file implements (SR-1211): VPAID 2.0, OMID 1.x verification, SIMID 1.0 or 1.1 — rendered only when the request declares support for the framework.\n",
  "enum": [
    "VPAID_2",
    "OMID_1",
    "SIMID_1_0",
    "SIMID_1_1"
  ],
  "x-enum-varnames": [
    "InteractiveApiFrameworkVPAID2",
    "InteractiveApiFrameworkOMID1",
    "InteractiveApiFrameworkSIMID10",
    "InteractiveApiFrameworkSIMID11"
  ]
}
InteractiveCreativeFile

schemas/InteractiveApiFramework

{
  "type": "object",
  "description": "VAST 4.x InteractiveCreativeFile carried by a video creative (SR-1211): the interactive layer (SIMID / VPAID) rendered alongside the media file when the player negotiates the api_framework.\n",
  "required": [
    "api_framework",
    "url"
  ],
  "properties": {
    "type": {
      "type": "string",
      "maxLength": 128,
      "description": "MIME type of the interactive file (e.g. text/html for SIMID, application/javascript for VPAID)."
    },
    "api_framework": {
      "$ref": "#/components/schemas/InteractiveApiFramework"
    },
    "url": {
      "type": "string",
      "maxLength": 2048,
      "description": "HTTPS URL of the interactive file."
    },
    "variable_duration": {
      "type": "boolean",
      "description": "True when the interactive layer may change the ad duration (VAST variableDuration)."
    }
  }
}
CreativeMediaUploadStatus

{
  "type": "string",
  "description": "Processing state of a media upload (SR-307); RECEIVED → VALIDATED → TRANSCODING → READY, or FAILED.",
  "enum": [
    "RECEIVED",
    "VALIDATED",
    "TRANSCODING",
    "READY",
    "FAILED"
  ],
  "x-enum-varnames": [
    "CreativeMediaUploadStatusRECEIVED",
    "CreativeMediaUploadStatusVALIDATED",
    "CreativeMediaUploadStatusTRANSCODING",
    "CreativeMediaUploadStatusREADY",
    "CreativeMediaUploadStatusFAILED"
  ]
}
CreativeMediaUploadForm

{
  "type": "object",
  "description": "multipart/form-data body of createCreativeMediaUpload (SR-307).",
  "required": [
    "file"
  ],
  "properties": {
    "file": {
      "type": "string",
      "format": "binary",
      "description": "The media bytes (video, audio, or image) for the creative."
    },
    "content_type": {
      "type": "string",
      "maxLength": 128,
      "description": "Override of the file part's Content-Type (e.g. video/mp4) when the client cannot set it on the part."
    }
  }
}
CreativeMediaUpload

schemas/CreativeMediaUploadStatus

{
  "type": "object",
  "description": "One media upload record (SR-307; creative_media_upload): the bytes are stored on receipt and validated / transcoded asynchronously; READY links the resulting media variant and a preview URL onto the creative.\n",
  "required": [
    "id",
    "creative_id",
    "status",
    "content_type",
    "bytes",
    "sha256",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Upload record id."
    },
    "creative_id": {
      "type": "string",
      "format": "uuid",
      "description": "The creative the media belongs to."
    },
    "status": {
      "$ref": "#/components/schemas/CreativeMediaUploadStatus"
    },
    "content_type": {
      "type": "string",
      "description": "Validated media MIME type (from the part or the content_type override)."
    },
    "bytes": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Size of the received file in bytes."
    },
    "sha256": {
      "type": "string",
      "description": "Hex SHA-256 of the received bytes (dedup key and integrity check)."
    },
    "media_variant_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The creative media variant produced from this upload; null until READY."
    },
    "preview_url": {
      "type": "string",
      "nullable": true,
      "description": "HTTPS preview of the processed media; null until READY."
    },
    "error": {
      "type": "string",
      "nullable": true,
      "description": "Failure reason when status is FAILED (unsupported type, corrupt file, transcode error); null otherwise."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the upload was received."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the status last changed."
    }
  }
}
CreativeReviewAction

{
  "type": "string",
  "enum": [
    "APPROVE",
    "REJECT"
  ]
}
CreativeReviewRequest

schemas/CreativeReviewAction

{
  "type": "object",
  "required": [
    "action"
  ],
  "description": "Body for reviewCreative (design 30 §2C). REJECT requires reason_code; APPROVE may carry one. The decision, actor, and time are recorded on the creative's read-only review audit fields.\n",
  "properties": {
    "action": {
      "$ref": "#/components/schemas/CreativeReviewAction"
    },
    "reason_code": {
      "type": "string",
      "description": "Machine-readable reason code; required when action=REJECT."
    },
    "feedback": {
      "type": "string",
      "description": "Free-text feedback for the creative owner."
    }
  }
}
CreativeList

schemas/Creative

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Creative"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
Audience

schemas/AudienceOriginschemas/EntityUsageschemas/AudienceStringRuleschemas/AudienceIntRuleschemas/AudienceGeoRuleschemas/AudienceMetroRuleschemas/AudiencePlacementRuleschemas/AudienceContentRulesschemas/AudienceEventMembershipRule

{
  "type": "object",
  "description": "Reusable targeting definition — docs/design/02-data-model.md \"Targeting\". Full rule set is admin-editable. On update, omit a field to leave it unchanged; when present, each rule array (geo, metros, placements, app_ids, …) and the content object fully replace the stored set (RIP-133, RIPTIDE-20).\n",
  "required": [
    "id",
    "tenant_id",
    "name"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "k1": {
      "type": "string"
    },
    "origin": {
      "readOnly": true,
      "description": "How the audience came to exist (MANUAL by default); set by the system, never by the API caller.",
      "allOf": [
        {
          "$ref": "#/components/schemas/AudienceOrigin"
        }
      ]
    },
    "usage": {
      "readOnly": true,
      "description": "Where the audience is referenced (REM-J \"Used by\"); counted at read time.",
      "allOf": [
        {
          "$ref": "#/components/schemas/EntityUsage"
        }
      ]
    },
    "k2": {
      "type": "string"
    },
    "k3": {
      "type": "string"
    },
    "k4": {
      "type": "string"
    },
    "keys_excluded": {
      "type": "boolean"
    },
    "ad_duration_enabled": {
      "type": "boolean"
    },
    "ad_duration_sec": {
      "type": "string"
    },
    "custom_rules": {
      "type": "string",
      "description": "JSON custom targeting rules."
    },
    "first_impression": {
      "type": "boolean"
    },
    "all_pods": {
      "type": "boolean"
    },
    "app_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "store_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "device_types": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceIntRule"
      }
    },
    "hardware": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "domains": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "zips": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "segments": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "app_segments": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "deal_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "brand_safety": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "geo": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceGeoRule"
      }
    },
    "metros": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceMetroRule"
      }
    },
    "placements": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudiencePlacementRule"
      }
    },
    "content": {
      "$ref": "#/components/schemas/AudienceContentRules"
    },
    "event_membership": {
      "type": "array",
      "description": "Event-fed membership rules (design 32 Phase 2 / design 33 §2.2). Matching events add this audience to the user's hot membership store for targeting.\n",
      "items": {
        "$ref": "#/components/schemas/AudienceEventMembershipRule"
      }
    },
    "targeting_expression": {
      "type": "string",
      "maxLength": 8192,
      "description": "Finite targeting expression (design 33 §3 / CP-12). JSON AST or compact S-expression over request.* and profile.* paths. Operators: and/or/not, eq/neq/lt/lte/gt/gte, in/not_in/contains, exists/not_exists, in_segment. Hard limits: depth≤8, nodes≤64, string≤256, in-set≤32 — rejected at write. Empty = no expression gate.\n"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
AudienceEventMembershipRule

{
  "type": "object",
  "required": [
    "event_kind"
  ],
  "properties": {
    "event_kind": {
      "type": "string",
      "enum": [
        "FILL",
        "IMPRESSION",
        "CLICK",
        "CONVERSION"
      ],
      "description": "Delivery or conversion event that seeds membership."
    },
    "conversion_label": {
      "type": "string",
      "pattern": "^[a-z0-9_-]{0,64}$",
      "description": "Optional CONVERSION label filter; empty matches any label."
    },
    "ttl_seconds": {
      "type": "integer",
      "minimum": 0,
      "maximum": 7776000,
      "description": "Membership TTL in seconds; 0 = platform default (30 days); max 90 days."
    },
    "excluded": {
      "type": "boolean",
      "description": "When true, membership fails the audience (suppression / exclude-if-member)."
    }
  }
}
AudienceCreate

schemas/AudienceStringRuleschemas/AudienceIntRuleschemas/AudienceGeoRuleschemas/AudienceMetroRuleschemas/AudiencePlacementRuleschemas/AudienceContentRulesschemas/AudienceEventMembershipRule

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "k1": {
      "type": "string"
    },
    "k2": {
      "type": "string"
    },
    "k3": {
      "type": "string"
    },
    "k4": {
      "type": "string"
    },
    "keys_excluded": {
      "type": "boolean"
    },
    "ad_duration_enabled": {
      "type": "boolean"
    },
    "ad_duration_sec": {
      "type": "string"
    },
    "custom_rules": {
      "type": "string"
    },
    "first_impression": {
      "type": "boolean"
    },
    "all_pods": {
      "type": "boolean"
    },
    "app_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "store_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "device_types": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceIntRule"
      }
    },
    "hardware": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "domains": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "zips": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "segments": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "app_segments": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "deal_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "brand_safety": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "geo": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceGeoRule"
      }
    },
    "metros": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceMetroRule"
      }
    },
    "placements": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudiencePlacementRule"
      }
    },
    "content": {
      "$ref": "#/components/schemas/AudienceContentRules"
    },
    "event_membership": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceEventMembershipRule"
      }
    },
    "targeting_expression": {
      "type": "string",
      "maxLength": 8192,
      "description": "Finite targeting expression AST (design 33 §3 / CP-12); empty clears."
    }
  }
}
AudienceUpdate

schemas/AudienceStringRuleschemas/AudienceIntRuleschemas/AudienceGeoRuleschemas/AudienceMetroRuleschemas/AudiencePlacementRuleschemas/AudienceContentRulesschemas/AudienceEventMembershipRule

{
  "type": "object",
  "required": [
    "name"
  ],
  "description": "Omit a property to leave it unchanged. When present, each rule array and the content object fully replace the stored set (including empty arrays or an empty content object to clear).\n",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "k1": {
      "type": "string"
    },
    "k2": {
      "type": "string"
    },
    "k3": {
      "type": "string"
    },
    "k4": {
      "type": "string"
    },
    "keys_excluded": {
      "type": "boolean"
    },
    "ad_duration_enabled": {
      "type": "boolean"
    },
    "ad_duration_sec": {
      "type": "string"
    },
    "custom_rules": {
      "type": "string"
    },
    "first_impression": {
      "type": "boolean"
    },
    "all_pods": {
      "type": "boolean"
    },
    "app_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "store_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "device_types": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceIntRule"
      }
    },
    "hardware": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "domains": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "zips": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "segments": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "app_segments": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "deal_ids": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "brand_safety": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceStringRule"
      }
    },
    "geo": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceGeoRule"
      }
    },
    "metros": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceMetroRule"
      }
    },
    "placements": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudiencePlacementRule"
      }
    },
    "content": {
      "$ref": "#/components/schemas/AudienceContentRules"
    },
    "event_membership": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AudienceEventMembershipRule"
      }
    },
    "targeting_expression": {
      "type": "string",
      "maxLength": 8192,
      "description": "Finite targeting expression AST (design 33 §3 / CP-12); omit to leave unchanged; empty string clears."
    }
  }
}
AudienceList

schemas/Audience

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Audience"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ReportGrain

{
  "type": "string",
  "description": "Time-bucket granularity (libs/reporting.Grain).",
  "enum": [
    "minute",
    "hour",
    "day"
  ]
}
ReportFilterOp

{
  "type": "string",
  "description": "Dimension filter predicate (libs/reporting.FilterOp).",
  "enum": [
    "eq",
    "neq",
    "in",
    "not_in"
  ]
}
ReportFilter

schemas/ReportFilterOp

{
  "type": "object",
  "required": [
    "dimension",
    "op",
    "values"
  ],
  "properties": {
    "dimension": {
      "type": "string",
      "description": "Catalog dimension name."
    },
    "op": {
      "$ref": "#/components/schemas/ReportFilterOp"
    },
    "values": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    }
  }
}
ReportOrderDir

{
  "type": "string",
  "enum": [
    "asc",
    "desc"
  ]
}
ReportOrderBy

schemas/ReportOrderDir

{
  "type": "object",
  "required": [
    "field"
  ],
  "properties": {
    "field": {
      "type": "string",
      "description": "period, a requested dimension, or a requested metric."
    },
    "dir": {
      "$ref": "#/components/schemas/ReportOrderDir"
    }
  }
}
ReportRunRequest

schemas/ReportFilterschemas/ReportOrderByschemas/ReportGrain

{
  "type": "object",
  "required": [
    "metrics",
    "from",
    "to"
  ],
  "properties": {
    "metrics": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string",
        "description": "A metric name from the reporting semantic-layer catalog (e.g. requests, bids, fills, impressions, completes, clicks, win_rate, fill_rate, ecpm, revenue_gross, revenue_net, profit) — see libs/reporting.Metrics().\n"
      }
    },
    "dimensions": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "A dimension name from the catalog (e.g. tenant_id, publisher, placement, campaign_order, line_item, creative, deal, partner, country, device_class, cell_id) — see libs/reporting.Dimensions().\n"
      }
    },
    "filters": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportFilter"
      },
      "description": "Dimension value filters applied before aggregation (tenant_id always forced)."
    },
    "order_by": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportOrderBy"
      }
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "Row cap (default 1000 when omitted)."
    },
    "from": {
      "type": "string",
      "format": "date-time"
    },
    "to": {
      "type": "string",
      "format": "date-time"
    },
    "grain": {
      "$ref": "#/components/schemas/ReportGrain"
    }
  }
}
ReportCatalogMetric

{
  "type": "object",
  "required": [
    "name",
    "unit",
    "description",
    "available",
    "money",
    "temperatures"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "unit": {
      "type": "string",
      "description": "count | ratio | money"
    },
    "description": {
      "type": "string"
    },
    "available": {
      "type": "boolean"
    },
    "unavailable_reason": {
      "type": "string"
    },
    "money": {
      "type": "boolean"
    },
    "temperatures": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "hot | warm | cold | conversion"
      }
    }
  }
}
ReportCatalogDimension

{
  "type": "object",
  "required": [
    "name",
    "description",
    "available",
    "temperatures"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "Dimension key (libs/reporting.Dimensions()); includes campaign_order, which expands line_item through the order map (SR-1233)."
    },
    "description": {
      "type": "string"
    },
    "available": {
      "type": "boolean"
    },
    "unavailable_reason": {
      "type": "string"
    },
    "temperatures": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}
ReportCatalog

schemas/ReportCatalogMetricschemas/ReportCatalogDimensionschemas/ReportGrain

{
  "type": "object",
  "required": [
    "metrics",
    "dimensions",
    "grains",
    "default_limit",
    "max_limit"
  ],
  "properties": {
    "metrics": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportCatalogMetric"
      }
    },
    "dimensions": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportCatalogDimension"
      }
    },
    "grains": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportGrain"
      }
    },
    "default_limit": {
      "type": "integer"
    },
    "max_limit": {
      "type": "integer"
    }
  }
}
ReportingChatRequest

{
  "type": "object",
  "required": [
    "message"
  ],
  "properties": {
    "session_id": {
      "type": "string",
      "description": "Opaque session id; omit to start a new session."
    },
    "message": {
      "type": "string",
      "minLength": 1
    },
    "financial_allowed": {
      "type": "boolean",
      "description": "When true, money-unit metrics may be queried (insight financial gate). Default false.\n"
    }
  }
}
ReportingChatEvidence

{
  "type": "object",
  "required": [
    "tool",
    "summary"
  ],
  "properties": {
    "tool": {
      "type": "string"
    },
    "summary": {
      "type": "string"
    },
    "table": {
      "type": "string"
    },
    "sql_hash": {
      "type": "string"
    },
    "methodology": {
      "type": "string"
    }
  }
}
ReportingChatReply

schemas/ReportingChatEvidenceschemas/ReportRunRequest

{
  "type": "object",
  "required": [
    "session_id",
    "reply",
    "evidence"
  ],
  "properties": {
    "session_id": {
      "type": "string"
    },
    "reply": {
      "type": "string"
    },
    "evidence": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportingChatEvidence"
      }
    },
    "apply_spec": {
      "$ref": "#/components/schemas/ReportRunRequest"
    }
  }
}
ReportRow

{
  "type": "object",
  "description": "One result row; keys are the requested dimension/metric names plus \"period\".",
  "additionalProperties": true
}
ReportRunResponse

schemas/ReportRowschemas/ReportGrain

{
  "type": "object",
  "required": [
    "rows",
    "table",
    "grain",
    "sql"
  ],
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportRow"
      }
    },
    "table": {
      "type": "string",
      "description": "The physical table the query router selected (hot/warm/cold)."
    },
    "grain": {
      "$ref": "#/components/schemas/ReportGrain"
    },
    "sql": {
      "type": "string",
      "description": "The compiled, parameterized SQL (values are bound as args, never interpolated) — returned for debugging/audit; safe to expose since it carries no literal values.\n"
    },
    "executed": {
      "type": "boolean",
      "description": "True if this ran against a live ClickHouse (RIPTIDE_CLICKHOUSE_DSN configured); false means rows is always empty and only the compiled query is returned.\n"
    }
  }
}
ReportLiveCounter

{
  "type": "object",
  "required": [
    "placement_id",
    "kind",
    "count"
  ],
  "properties": {
    "placement_id": {
      "type": "string"
    },
    "kind": {
      "type": "string"
    },
    "count": {
      "type": "integer",
      "format": "int64"
    }
  }
}
ReportLiveResponse

schemas/ReportLiveCounter

{
  "type": "object",
  "required": [
    "items",
    "window_minutes"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportLiveCounter"
      }
    },
    "window_minutes": {
      "type": "integer",
      "description": "Sliding window size, in minutes, the counters are summed over."
    }
  }
}
ReportConfig

schemas/ReportFilterschemas/ReportOrderByschemas/ReportGrainschemas/LifecycleStatusschemas/ReportConfigSchedule

{
  "type": "object",
  "description": "A saved, reusable report definition over the semantic layer (P3-07 / RIPTIDE-58) — a name plus the same metrics/dimensions/filters/order/limit/grain shape POST .../reports/run accepts, so it can be re-run or scheduled for delivery without re-specifying the query.\n",
  "required": [
    "id",
    "tenant_id",
    "name",
    "metrics",
    "grain",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "metrics": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string",
        "description": "A metric name from libs/reporting.Metrics()."
      }
    },
    "dimensions": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "A dimension name from libs/reporting.Dimensions()."
      }
    },
    "filters": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportFilter"
      }
    },
    "order_by": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportOrderBy"
      }
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000
    },
    "grain": {
      "$ref": "#/components/schemas/ReportGrain"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Set when the config was created through the publisher portal (SR-1010); every run injects `publisher = <public_id>`."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "tile": {
      "type": "boolean",
      "description": "Pinned as a dashboard tile (SR-1233 tiles as saved definitions)."
    },
    "tile_position": {
      "type": "integer",
      "minimum": 0,
      "description": "Tile order on the dashboard (0 = first); ignored unless tile is true."
    },
    "schedule": {
      "readOnly": true,
      "description": "The scheduled delivery created alongside the config (SR-1233 save + schedule in one dialog); absent when none was requested.",
      "allOf": [
        {
          "$ref": "#/components/schemas/ReportConfigSchedule"
        }
      ]
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ReportConfigCreate

schemas/ReportFilterschemas/ReportOrderByschemas/ReportGrainschemas/ReportConfigScheduleCreate

{
  "type": "object",
  "required": [
    "name",
    "metrics"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "metrics": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "dimensions": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "filters": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportFilter"
      }
    },
    "order_by": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportOrderBy"
      }
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000
    },
    "grain": {
      "$ref": "#/components/schemas/ReportGrain"
    },
    "tile": {
      "type": "boolean",
      "description": "Pin as a dashboard tile; see ReportConfig.tile."
    },
    "tile_position": {
      "type": "integer",
      "minimum": 0,
      "description": "Tile order on the dashboard; see ReportConfig.tile_position."
    },
    "schedule": {
      "description": "Create a scheduled delivery for the new config in the same call (SR-1233); the created schedule is returned as ReportConfig.schedule with its secret exactly once.",
      "allOf": [
        {
          "$ref": "#/components/schemas/ReportConfigScheduleCreate"
        }
      ]
    }
  }
}
ReportConfigUpdate

schemas/ReportFilterschemas/ReportOrderByschemas/ReportGrain

{
  "type": "object",
  "required": [
    "name",
    "metrics"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "metrics": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      }
    },
    "dimensions": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "filters": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportFilter"
      }
    },
    "order_by": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportOrderBy"
      }
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000
    },
    "grain": {
      "$ref": "#/components/schemas/ReportGrain"
    },
    "tile": {
      "type": "boolean",
      "description": "Pin as a dashboard tile; see ReportConfig.tile."
    },
    "tile_position": {
      "type": "integer",
      "minimum": 0,
      "description": "Tile order on the dashboard; see ReportConfig.tile_position."
    }
  }
}
ReportConfigList

schemas/ReportConfig

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ReportConfig"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ScheduledReportCadence

{
  "type": "string",
  "description": "Recurrence interval (libs/reporting.Cadence).",
  "enum": [
    "hourly",
    "daily",
    "weekly"
  ]
}
ScheduledReport

schemas/ScheduledReportCadenceschemas/LifecycleStatus

{
  "type": "object",
  "description": "Recurring delivery of a saved report_config's result to a webhook-style destination (HMAC-signed via libs/webhooks). destination_secret is write-only — never present on a GET/list/update response; only the create response returns it, exactly once.\n",
  "required": [
    "id",
    "tenant_id",
    "report_config_id",
    "cadence",
    "destination_url",
    "status",
    "next_run_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "report_config_id": {
      "type": "string",
      "format": "uuid"
    },
    "cadence": {
      "$ref": "#/components/schemas/ScheduledReportCadence"
    },
    "destination_url": {
      "type": "string",
      "format": "uri",
      "description": "Where each run is delivered (SR-1214). https://… — an HMAC-signed webhook POST through the durable outbox (retried on the default policy); mailto:a@x,b@y — the result as an e-mail with a CSV attachment; export-destination://{export_destination_id} — a JSONL or Parquet file written to that tenant export destination (its format/prefix apply). An optional tz=<IANA zone> query parameter (e.g. ?tz=America/New_York) makes the cadence calendar-aware in that zone: hourly = next top of hour, daily = next local midnight, weekly = next local Monday 00:00 (UTC when omitted).\n"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Inherited from a publisher-scoped report config (SR-1010)."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "last_run_at": {
      "type": "string",
      "format": "date-time"
    },
    "next_run_at": {
      "type": "string",
      "format": "date-time"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ScheduledReportCreate

schemas/ScheduledReportCadence

{
  "type": "object",
  "required": [
    "report_config_id",
    "cadence",
    "destination_url"
  ],
  "properties": {
    "report_config_id": {
      "type": "string",
      "format": "uuid"
    },
    "cadence": {
      "$ref": "#/components/schemas/ScheduledReportCadence"
    },
    "destination_url": {
      "type": "string",
      "format": "uri",
      "minLength": 1
    }
  }
}
ScheduledReportCreated

schemas/ScheduledReport

{
  "description": "The created scheduled report plus its signing secret (returned once, at creation only).",
  "allOf": [
    {
      "$ref": "#/components/schemas/ScheduledReport"
    },
    {
      "type": "object",
      "required": [
        "destination_secret"
      ],
      "properties": {
        "destination_secret": {
          "type": "string",
          "description": "HMAC-SHA256 signing secret (libs/webhooks.Sign/Verify) for this schedule's deliveries. Shown once; store it — the API never returns it again.\n"
        }
      }
    }
  ]
}
ScheduledReportUpdate

schemas/ScheduledReportCadence

{
  "type": "object",
  "required": [
    "cadence",
    "destination_url"
  ],
  "properties": {
    "cadence": {
      "$ref": "#/components/schemas/ScheduledReportCadence"
    },
    "destination_url": {
      "type": "string",
      "format": "uri",
      "minLength": 1
    }
  }
}
ScheduledReportList

schemas/ScheduledReport

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ScheduledReport"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ScheduledReportRunResult

{
  "type": "object",
  "required": [
    "delivered",
    "row_count",
    "delivered_at"
  ],
  "properties": {
    "delivered": {
      "type": "boolean",
      "description": "True if the destination accepted the delivery (a 2xx response)."
    },
    "row_count": {
      "type": "integer",
      "description": "Number of report rows included in the delivered payload."
    },
    "status_code": {
      "type": "integer",
      "description": "The destination's HTTP response status code, if a delivery attempt was made."
    },
    "delivered_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
WebhookEventType

{
  "type": "string",
  "description": "A cataloged webhook event name (libs/webhooks.EventType).",
  "enum": [
    "delivery.impression",
    "delivery.click",
    "delivery.line_item_ended",
    "delivery.alert_fired",
    "billing.invoice_created",
    "billing.payment_failed",
    "creative.approved",
    "creative.rejected",
    "reporting.scheduled_report_delivered"
  ]
}
WebhookSubscription

schemas/WebhookEventType

{
  "type": "object",
  "description": "A tenant's webhook registration. secret is write-only — never present on a GET/list/update response; only the create response returns it, exactly once.\n",
  "required": [
    "id",
    "tenant_id",
    "url",
    "events",
    "active"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "url": {
      "type": "string",
      "format": "uri"
    },
    "events": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WebhookEventType"
      },
      "minItems": 1
    },
    "active": {
      "type": "boolean"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
WebhookSubscriptionCreate

schemas/WebhookEventType

{
  "type": "object",
  "required": [
    "url",
    "events"
  ],
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "minLength": 1
    },
    "events": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WebhookEventType"
      },
      "minItems": 1
    },
    "active": {
      "type": "boolean",
      "default": true
    }
  }
}
WebhookSubscriptionCreated

schemas/WebhookSubscription

{
  "description": "The created subscription plus its signing secret (returned once, at creation only).",
  "allOf": [
    {
      "$ref": "#/components/schemas/WebhookSubscription"
    },
    {
      "type": "object",
      "required": [
        "secret"
      ],
      "properties": {
        "secret": {
          "type": "string",
          "description": "HMAC-SHA256 signing secret (libs/webhooks.Sign/Verify) for this subscription's deliveries. Shown once; store it — the API never returns it again.\n"
        }
      }
    }
  ]
}
WebhookSubscriptionUpdate

schemas/WebhookEventType

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "minLength": 1
    },
    "events": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WebhookEventType"
      },
      "minItems": 1
    },
    "active": {
      "type": "boolean"
    }
  }
}
WebhookSubscriptionList

schemas/WebhookSubscription

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WebhookSubscription"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
WebhookDeliveryStatus

{
  "type": "string",
  "description": "Outbox row state: PENDING (waiting for next_attempt_at), IN_FLIGHT (leased by a runner), DELIVERED (a 2xx), DEAD (dead-lettered after the retry policy's max attempts, or the target became unresolvable). DEAD rows stay listable and replayable.\n",
  "enum": [
    "PENDING",
    "IN_FLIGHT",
    "DELIVERED",
    "DEAD"
  ]
}
WebhookDelivery

schemas/WebhookEventTypeschemas/WebhookDeliveryStatus

{
  "type": "object",
  "description": "One delivery of one event to one subscription, with its attempt history.",
  "required": [
    "id",
    "tenant_id",
    "webhook_subscription_id",
    "event_id",
    "event_type",
    "status",
    "attempts",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "webhook_subscription_id": {
      "type": "string",
      "format": "uuid"
    },
    "event_id": {
      "type": "string",
      "description": "The event's id (X-Riptide-Webhook payload `id`); stable across retries and replays."
    },
    "event_type": {
      "$ref": "#/components/schemas/WebhookEventType"
    },
    "status": {
      "$ref": "#/components/schemas/WebhookDeliveryStatus"
    },
    "attempts": {
      "type": "integer",
      "minimum": 0
    },
    "next_attempt_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the next attempt is due (PENDING only)."
    },
    "last_status_code": {
      "type": "integer",
      "description": "HTTP status of the last attempt (0 when the request never got a response)."
    },
    "last_error": {
      "type": "string"
    },
    "delivered_at": {
      "type": "string",
      "format": "date-time"
    },
    "replay_of": {
      "type": "string",
      "format": "uuid",
      "description": "The delivery this one was replayed from, when it is a replay."
    },
    "payload": {
      "type": "object",
      "additionalProperties": true,
      "description": "The exact event payload that is signed and sent."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
WebhookDeliveryList

schemas/WebhookDelivery

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/WebhookDelivery"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
WebhookSecretRotateRequest

{
  "type": "object",
  "properties": {
    "grace_seconds": {
      "type": "integer",
      "minimum": 0,
      "maximum": 604800,
      "default": 86400,
      "description": "How long the previous secret keeps co-signing deliveries after rotation."
    }
  }
}
WebhookSecretRotated

schemas/WebhookSubscription

{
  "description": "The subscription after rotation plus its new signing secret (returned once).",
  "allOf": [
    {
      "$ref": "#/components/schemas/WebhookSubscription"
    },
    {
      "type": "object",
      "required": [
        "secret",
        "secret_version",
        "previous_secret_expires_at"
      ],
      "properties": {
        "secret": {
          "type": "string",
          "description": "The new HMAC-SHA256 signing secret. Shown once; the API never returns it again."
        },
        "secret_version": {
          "type": "integer"
        },
        "previous_secret_expires_at": {
          "type": "string",
          "format": "date-time",
          "description": "Until this instant deliveries also carry a signature under the previous secret."
        }
      }
    }
  ]
}
TenantHealth

{
  "type": "object",
  "required": [
    "tenant_id",
    "endpoint_error_rates",
    "governor_shed_counts",
    "window_minutes",
    "checked_at"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "plan_version": {
      "type": "integer",
      "format": "int64",
      "nullable": true,
      "description": "The serving plan version last observed for this tenant's cell, when this console instance has a plan-store binding configured. Null is a documented gap, not a fabricated value — see docs/spec/operability.md.\n"
    },
    "endpoint_error_rates": {
      "type": "object",
      "additionalProperties": {
        "type": "number"
      },
      "description": "Per-endpoint error rate (errors/requests) over the retained window (libs/health.InMemoryReporter). Empty until something records into this console instance's own counters — see docs/spec/operability.md for the cross-process scope note.\n"
    },
    "governor_shed_counts": {
      "type": "object",
      "additionalProperties": {
        "type": "integer",
        "format": "int64"
      },
      "description": "Per-\"scope:id\" governor shed count over the retained window, when fed."
    },
    "window_minutes": {
      "type": "integer",
      "description": "The retained window (minutes) the counts above were summed over."
    },
    "checked_at": {
      "type": "string",
      "format": "date-time"
    },
    "requests": {
      "type": "integer",
      "format": "int64",
      "nullable": true,
      "description": "Sum of requests over the window from riptide.report_event_rollup_minute, when a ClickHouse DSN is configured. Null (not zero) when ClickHouse is not configured — a documented degrade, see docs/spec/operability.md.\n"
    },
    "fills": {
      "type": "integer",
      "format": "int64",
      "nullable": true,
      "description": "Sum of fills over the window, from the same ClickHouse source as requests."
    },
    "impressions": {
      "type": "integer",
      "format": "int64",
      "nullable": true,
      "description": "Sum of impressions over the window, from the same ClickHouse source as requests."
    },
    "revenue_net": {
      "type": "string",
      "nullable": true,
      "description": "Sum of net-recognized revenue over the window (decimal string, 4dp), from the same ClickHouse source as requests.\n"
    },
    "fill_rate": {
      "type": "number",
      "nullable": true,
      "description": "fills / requests over the window (0 when requests is 0), from the same ClickHouse source as requests."
    }
  }
}
PublisherBulkImportRequest

schemas/PublisherCreate

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "$ref": "#/components/schemas/PublisherCreate"
      }
    },
    "dry_run": {
      "type": "boolean",
      "default": false,
      "description": "When true, validate every row and report what would happen without persisting anything."
    }
  }
}
PublisherBulkImportRow

schemas/Publisher

{
  "type": "object",
  "required": [
    "index",
    "status"
  ],
  "properties": {
    "index": {
      "type": "integer",
      "description": "Position of this row in the request's items array."
    },
    "status": {
      "type": "string",
      "enum": [
        "would_create",
        "created",
        "error"
      ]
    },
    "publisher": {
      "$ref": "#/components/schemas/Publisher"
    },
    "error": {
      "type": "string"
    }
  }
}
PublisherBulkImportResponse

schemas/PublisherBulkImportRow

{
  "type": "object",
  "required": [
    "rows"
  ],
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PublisherBulkImportRow"
      }
    }
  }
}
PlacementBulkImportRequest

schemas/PlacementCreate

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "$ref": "#/components/schemas/PlacementCreate"
      }
    },
    "dry_run": {
      "type": "boolean",
      "default": false,
      "description": "When true, validate every row and report what would happen without persisting anything."
    }
  }
}
PlacementBulkImportRow

schemas/Placement

{
  "type": "object",
  "required": [
    "index",
    "status"
  ],
  "properties": {
    "index": {
      "type": "integer",
      "description": "Position of this row in the request's items array."
    },
    "status": {
      "type": "string",
      "enum": [
        "would_create",
        "created",
        "error"
      ]
    },
    "placement": {
      "$ref": "#/components/schemas/Placement"
    },
    "error": {
      "type": "string"
    }
  }
}
PlacementBulkImportResponse

schemas/PlacementBulkImportRow

{
  "type": "object",
  "required": [
    "rows"
  ],
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PlacementBulkImportRow"
      }
    }
  }
}
DemandPartnerBulkImportRequest

schemas/DemandPartnerCreate

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "$ref": "#/components/schemas/DemandPartnerCreate"
      }
    },
    "dry_run": {
      "type": "boolean",
      "default": false,
      "description": "When true, validate every row and report what would happen without persisting anything."
    }
  }
}
DemandPartnerBulkImportRow

schemas/DemandPartner

{
  "type": "object",
  "required": [
    "index",
    "status"
  ],
  "properties": {
    "index": {
      "type": "integer",
      "description": "Position of this row in the request's items array."
    },
    "status": {
      "type": "string",
      "enum": [
        "would_create",
        "created",
        "error"
      ]
    },
    "demand_partner": {
      "$ref": "#/components/schemas/DemandPartner"
    },
    "error": {
      "type": "string"
    }
  }
}
DemandPartnerBulkImportResponse

schemas/DemandPartnerBulkImportRow

{
  "type": "object",
  "required": [
    "rows"
  ],
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DemandPartnerBulkImportRow"
      }
    }
  }
}
CampaignOrderBulkImportRequest

schemas/CampaignOrderCreate

{
  "type": "object",
  "required": [
    "items"
  ],
  "description": "CP-11 bulk upsert of campaign orders by `ref` (design 37 §4). Each item must carry a non-empty `ref` for idempotent identity. `dry_run` validates without persisting.\n",
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "$ref": "#/components/schemas/CampaignOrderCreate"
      }
    },
    "dry_run": {
      "type": "boolean",
      "default": false,
      "description": "When true, validate every row and report what would happen without persisting."
    }
  }
}
CampaignOrderBulkImportRow

schemas/CampaignOrder

{
  "type": "object",
  "required": [
    "index",
    "status"
  ],
  "properties": {
    "index": {
      "type": "integer",
      "description": "Position of this row in the request's items array."
    },
    "status": {
      "type": "string",
      "enum": [
        "would_create",
        "would_update",
        "created",
        "updated",
        "error"
      ]
    },
    "campaign_order": {
      "$ref": "#/components/schemas/CampaignOrder"
    },
    "error": {
      "type": "string"
    }
  }
}
CampaignOrderBulkImportResponse

schemas/CampaignOrderBulkImportRow

{
  "type": "object",
  "required": [
    "rows"
  ],
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CampaignOrderBulkImportRow"
      }
    }
  }
}
CreativeBulkImportRequest

schemas/CreativeCreate

{
  "type": "object",
  "required": [
    "items"
  ],
  "description": "CP-11 bulk upsert of creatives by `ref` (design 37 §4). Each item must carry a non-empty `ref` for idempotent identity. `dry_run` validates without persisting.\n",
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "$ref": "#/components/schemas/CreativeCreate"
      }
    },
    "dry_run": {
      "type": "boolean",
      "default": false,
      "description": "When true, validate every row and report what would happen without persisting."
    }
  }
}
CreativeBulkImportRow

schemas/Creative

{
  "type": "object",
  "required": [
    "index",
    "status"
  ],
  "properties": {
    "index": {
      "type": "integer",
      "description": "Position of this row in the request's items array."
    },
    "status": {
      "type": "string",
      "enum": [
        "would_create",
        "would_update",
        "created",
        "updated",
        "error"
      ]
    },
    "creative": {
      "$ref": "#/components/schemas/Creative"
    },
    "error": {
      "type": "string"
    }
  }
}
CreativeBulkImportResponse

schemas/CreativeBulkImportRow

{
  "type": "object",
  "required": [
    "rows"
  ],
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CreativeBulkImportRow"
      }
    }
  }
}
DoctorCheck

{
  "type": "object",
  "required": [
    "name",
    "set"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "set": {
      "type": "boolean"
    }
  }
}
DoctorIssue

{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "string"
    },
    "message": {
      "type": "string"
    }
  }
}
DoctorResult

schemas/DoctorCheckschemas/DoctorIssue

{
  "type": "object",
  "required": [
    "checks",
    "issues"
  ],
  "properties": {
    "checks": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DoctorCheck"
      }
    },
    "issues": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DoctorIssue"
      }
    }
  }
}
DecisionStageFilter

{
  "type": "object",
  "required": [
    "stage",
    "in",
    "out"
  ],
  "properties": {
    "stage": {
      "type": "string"
    },
    "in": {
      "type": "integer"
    },
    "out": {
      "type": "integer"
    },
    "removed_by_reason": {
      "type": "object",
      "additionalProperties": {
        "type": "integer"
      },
      "description": "Count of removed candidates per reason code, for stages that removed any."
    }
  }
}
DecisionTraceInput

schemas/DecisionStageFilter

{
  "type": "object",
  "properties": {
    "stages": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DecisionStageFilter"
      }
    },
    "winner_rationale": {
      "type": "string"
    }
  }
}
ExplainRequestInput

schemas/DecisionTraceInput

{
  "type": "object",
  "properties": {
    "decision_trace": {
      "$ref": "#/components/schemas/DecisionTraceInput"
    },
    "request_id": {
      "type": "string",
      "description": "Explain v1 fallback (RIP-96): when decision_trace is omitted and this console is configured with a ClickHouse DSN, request_id is looked up directly against riptide.ad_event (Tempo+CH join, docs/spec/observability.md) instead of requiring a caller-supplied trace. Ignored when decision_trace is present.\n"
    }
  }
}
ExplainResult

{
  "type": "object",
  "required": [
    "summary"
  ],
  "properties": {
    "summary": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Human-readable stage-by-stage lines, ending with the winner rationale."
    },
    "winner_rationale": {
      "type": "string"
    }
  }
}
DiagnoseDeliveryInput

{
  "type": "object",
  "required": [
    "line_item_ref"
  ],
  "properties": {
    "line_item_ref": {
      "type": "string",
      "description": "Line item reference code to diagnose."
    }
  }
}
DiagnoseDeliveryResult

{
  "type": "object",
  "required": [
    "blocking_issues",
    "checked"
  ],
  "properties": {
    "blocking_issues": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "checked": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}
PreflightChangeInput

{
  "type": "object",
  "required": [
    "entity_kind",
    "proposed"
  ],
  "properties": {
    "entity_kind": {
      "type": "string",
      "description": "Entity kind the change targets (line_item|placement|route|fee_schedule|campaign_order|creative|audience|...)."
    },
    "current": {
      "type": "object",
      "additionalProperties": true,
      "description": "Current field values, as a flat map of field name -> value. Omitted fields are treated as absent (nil)."
    },
    "proposed": {
      "type": "object",
      "additionalProperties": true,
      "description": "Proposed field changes, as a flat map of field name -> new value."
    }
  }
}
PreflightFieldChange

{
  "type": "object",
  "description": "One before/after value pair. Either side may be any JSON value or absent.",
  "properties": {
    "before": {},
    "after": {}
  }
}
PreflightChangeResult

schemas/PreflightFieldChange

{
  "type": "object",
  "required": [
    "would_apply",
    "warnings",
    "diff"
  ],
  "properties": {
    "would_apply": {
      "type": "boolean",
      "description": "Whether the change looks structurally safe to apply."
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "diff": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/PreflightFieldChange"
      }
    }
  }
}
ForecastConfidence

{
  "type": "string",
  "description": "Coarse confidence from historical sample size (design 36) — not a model probability. LOW = fewer than 7 history days; MEDIUM = 7–27; HIGH = 28+.\n",
  "enum": [
    "LOW",
    "MEDIUM",
    "HIGH"
  ]
}
ForecastSlice

{
  "type": "object",
  "description": "Supply slice dimensions assumed for the forecast (placement required in v1).",
  "required": [
    "placement_id"
  ],
  "properties": {
    "placement_id": {
      "type": "string",
      "format": "uuid"
    },
    "country": {
      "type": "string",
      "description": "Optional ISO-3166-1 alpha-2 country filter on the history rollup."
    },
    "app_or_site": {
      "type": "string",
      "description": "Optional app/site dimension filter (v1 reserved; ignored when empty)."
    }
  }
}
ForecastRange

{
  "type": "object",
  "description": "Inclusive UTC calendar-day range for the forecast window.",
  "required": [
    "start_day",
    "end_day"
  ],
  "properties": {
    "start_day": {
      "type": "string",
      "format": "date",
      "description": "Inclusive start (YYYY-MM-DD, UTC)."
    },
    "end_day": {
      "type": "string",
      "format": "date",
      "description": "Inclusive end (YYYY-MM-DD, UTC)."
    }
  }
}
ForecastProposal

schemas/PriorityClass

{
  "type": "object",
  "description": "Draft flight used for deliverable forecast (design 36 §3.1).",
  "required": [
    "priority_class",
    "goal_impressions",
    "start_day",
    "end_day"
  ],
  "properties": {
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "goal_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Proposed lifetime impression goal for the flight."
    },
    "start_day": {
      "type": "string",
      "format": "date"
    },
    "end_day": {
      "type": "string",
      "format": "date"
    }
  }
}
ForecastAvailabilityRequest

schemas/ForecastSliceschemas/ForecastRangeschemas/PriorityClassschemas/ForecastBooking

{
  "type": "object",
  "description": "Availability forecast input. Booked demand is loaded from the tenant's ACTIVE/PAUSED line items unless bookings are supplied explicitly (agent/test override).\n",
  "required": [
    "slice",
    "window",
    "priority_class"
  ],
  "properties": {
    "slice": {
      "$ref": "#/components/schemas/ForecastSlice"
    },
    "window": {
      "$ref": "#/components/schemas/ForecastRange"
    },
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "seasonality_factor": {
      "type": "string",
      "description": "Optional decimal seasonality multiplier (default \"1.0\"). Applied to replayed capacity. Must be > 0 when set.\n"
    },
    "lookback_days": {
      "type": "integer",
      "minimum": 1,
      "maximum": 90,
      "description": "History window in days ending before as-of (default 28)."
    },
    "bookings": {
      "type": "array",
      "description": "Optional explicit bookings; when omitted the console loads ACTIVE/PAUSED line items.",
      "items": {
        "$ref": "#/components/schemas/ForecastBooking"
      }
    }
  }
}
ForecastDeliveryRequest

schemas/ForecastSliceschemas/ForecastProposalschemas/ForecastBooking

{
  "type": "object",
  "description": "Delivery forecast input — availability inputs plus a proposal flight.",
  "required": [
    "slice",
    "proposal"
  ],
  "properties": {
    "slice": {
      "$ref": "#/components/schemas/ForecastSlice"
    },
    "proposal": {
      "$ref": "#/components/schemas/ForecastProposal"
    },
    "seasonality_factor": {
      "type": "string"
    },
    "lookback_days": {
      "type": "integer",
      "minimum": 1,
      "maximum": 90
    },
    "bookings": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ForecastBooking"
      }
    },
    "sample_requests": {
      "type": "integer",
      "minimum": 100,
      "maximum": 100000,
      "description": "Forecast v2 (SR-1238b): number of sampled requests to replay the proposal's targeting against. When set the response carries p10 / p50 / p90, the fill / IVT / viewability adjustments and the contention rows; omitted keeps the v1 point estimate.\n"
    }
  }
}
ForecastBooking

schemas/PriorityClass

{
  "type": "object",
  "description": "One booked line item used for contention math.",
  "required": [
    "ref",
    "priority_class",
    "goal_impressions"
  ],
  "properties": {
    "ref": {
      "type": "string",
      "description": "Line item ref (or draft id) for explainability."
    },
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "goal_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "start_day": {
      "type": "string",
      "format": "date"
    },
    "end_day": {
      "type": "string",
      "format": "date"
    }
  }
}
ForecastMetrics

schemas/ForecastConfidence

{
  "type": "object",
  "required": [
    "capacity",
    "booked",
    "available",
    "confidence"
  ],
  "properties": {
    "capacity": {
      "type": "integer",
      "format": "int64",
      "description": "Estimated eligible requests/impressions in the range."
    },
    "booked": {
      "type": "integer",
      "format": "int64",
      "description": "Estimated impressions consumed by higher-or-equal priority bookings."
    },
    "available": {
      "type": "integer",
      "format": "int64",
      "description": "Residual capacity at the queried priority band (max 0)."
    },
    "confidence": {
      "$ref": "#/components/schemas/ForecastConfidence"
    }
  }
}
AvailabilityForecastResult

schemas/ForecastSliceschemas/ForecastRangeschemas/PriorityClassschemas/ForecastMetrics

{
  "type": "object",
  "required": [
    "slice",
    "window",
    "priority_class",
    "metrics",
    "as_of",
    "history_days"
  ],
  "description": "Availability forecast result body (named distinctly from oapi-codegen's ForecastAvailabilityResponse client wrapper).\n",
  "properties": {
    "slice": {
      "$ref": "#/components/schemas/ForecastSlice"
    },
    "window": {
      "$ref": "#/components/schemas/ForecastRange"
    },
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "metrics": {
      "$ref": "#/components/schemas/ForecastMetrics"
    },
    "as_of": {
      "type": "string",
      "format": "date-time",
      "description": "Injected clock instant used for the run."
    },
    "history_days": {
      "type": "integer",
      "description": "Count of distinct history days with non-zero request volume used in the replay."
    },
    "seasonality_factor": {
      "type": "string"
    }
  }
}
DeliveryForecastResult

schemas/ForecastSliceschemas/ForecastProposalschemas/ForecastMetricsschemas/ForecastAdjustmentsschemas/ForecastContention

{
  "type": "object",
  "required": [
    "slice",
    "proposal",
    "metrics",
    "deliverable",
    "shortfall",
    "as_of",
    "history_days"
  ],
  "description": "Delivery forecast result body (named distinctly from oapi-codegen's ForecastDeliveryResponse client wrapper).\n",
  "properties": {
    "slice": {
      "$ref": "#/components/schemas/ForecastSlice"
    },
    "proposal": {
      "$ref": "#/components/schemas/ForecastProposal"
    },
    "metrics": {
      "$ref": "#/components/schemas/ForecastMetrics"
    },
    "deliverable": {
      "type": "integer",
      "format": "int64",
      "description": "Expected delivery for the proposal under even pacing (min of available and goal)."
    },
    "shortfall": {
      "type": "integer",
      "format": "int64",
      "description": "goal_impressions − deliverable (0 when fully deliverable)."
    },
    "as_of": {
      "type": "string",
      "format": "date-time"
    },
    "history_days": {
      "type": "integer"
    },
    "seasonality_factor": {
      "type": "string"
    },
    "p10": {
      "type": "integer",
      "format": "int64",
      "description": "Forecast v2: 10th-percentile deliverable impressions over the sampled replay (pessimistic)."
    },
    "p50": {
      "type": "integer",
      "format": "int64",
      "description": "Forecast v2: median deliverable impressions over the sampled replay."
    },
    "p90": {
      "type": "integer",
      "format": "int64",
      "description": "Forecast v2: 90th-percentile deliverable impressions over the sampled replay (optimistic)."
    },
    "adjustments": {
      "description": "Forecast v2 (SR-1238b): the multiplicative adjustments applied to raw capacity.",
      "allOf": [
        {
          "$ref": "#/components/schemas/ForecastAdjustments"
        }
      ]
    },
    "contention": {
      "type": "array",
      "description": "Forecast v2 (SR-1238b): the bookings whose targeting overlaps the proposal and how much they take.",
      "items": {
        "$ref": "#/components/schemas/ForecastContention"
      }
    }
  }
}
Platform

{
  "type": "object",
  "description": "One row of the global device / app-store platform catalog (migration 0086 seed).",
  "required": [
    "id",
    "name"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string",
      "description": "Stable snake_case platform key (ios, android, roku, web, ...)."
    }
  }
}
PlatformList

schemas/Platform

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Platform"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
InventoryAdsTxtStatus

{
  "type": "string",
  "description": "Last ads.txt verification outcome for a domain: UNCHECKED (never crawled), OK (every expected seller line present), MISSING (no ads.txt), MISMATCH (file present but lines missing). Written by the supply-transparency verify path; read-only on the API.\n",
  "enum": [
    "UNCHECKED",
    "OK",
    "MISSING",
    "MISMATCH"
  ],
  "x-enum-varnames": [
    "InventoryAdsTxtStatusUNCHECKED",
    "InventoryAdsTxtStatusOK",
    "InventoryAdsTxtStatusMISSING",
    "InventoryAdsTxtStatusMISMATCH"
  ]
}
InventoryCostType

{
  "type": "string",
  "description": "Publisher cost model for a domain — a REVSHARE fraction, or a CPM / FLAT money amount.",
  "enum": [
    "REVSHARE",
    "CPM",
    "FLAT"
  ],
  "x-enum-varnames": [
    "InventoryCostTypeREVSHARE",
    "InventoryCostTypeCPM",
    "InventoryCostTypeFLAT"
  ]
}
InventoryDomain

schemas/InventoryAdsTxtStatusschemas/InventoryCostTypeschemas/LifecycleStatus

{
  "type": "object",
  "description": "Web-domain inventory record (docs/design/inventory-tooling.md): the site-side counterpart of App. floor / cost_value are decimal strings (4 dp); categories are IAB content taxonomy ids (docs/spec/taxonomies.md).\n",
  "required": [
    "id",
    "tenant_id",
    "hostname",
    "ads_txt_status",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning publisher, when assigned."
    },
    "hostname": {
      "type": "string",
      "description": "Lower-case registrable host, no scheme or path."
    },
    "site_name": {
      "type": "string"
    },
    "ads_txt_url": {
      "type": "string",
      "description": "Explicit ads.txt location; empty means https://<hostname>/ads.txt."
    },
    "ads_txt_status": {
      "$ref": "#/components/schemas/InventoryAdsTxtStatus"
    },
    "ads_txt_checked_at": {
      "type": "string",
      "format": "date-time"
    },
    "floor": {
      "type": "string",
      "description": "CPM floor (decimal string, 4 dp); omitted = inherit."
    },
    "cost_type": {
      "$ref": "#/components/schemas/InventoryCostType"
    },
    "cost_value": {
      "type": "string",
      "description": "Fraction for REVSHARE (e.g. \"0.7000\"), money for CPM / FLAT."
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "keywords": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
InventoryDomainCreate

schemas/InventoryCostType

{
  "type": "object",
  "required": [
    "hostname"
  ],
  "properties": {
    "hostname": {
      "type": "string",
      "minLength": 1
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid"
    },
    "site_name": {
      "type": "string"
    },
    "ads_txt_url": {
      "type": "string"
    },
    "floor": {
      "type": "string"
    },
    "cost_type": {
      "$ref": "#/components/schemas/InventoryCostType"
    },
    "cost_value": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "keywords": {
      "type": "string"
    }
  }
}
InventoryDomainUpdate

schemas/InventoryCostType

{
  "type": "object",
  "description": "Partial update — omitted fields keep their stored value; categories present replaces the set.",
  "properties": {
    "publisher_id": {
      "type": "string",
      "format": "uuid"
    },
    "site_name": {
      "type": "string"
    },
    "ads_txt_url": {
      "type": "string"
    },
    "floor": {
      "type": "string"
    },
    "cost_type": {
      "$ref": "#/components/schemas/InventoryCostType"
    },
    "cost_value": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "keywords": {
      "type": "string"
    }
  }
}
InventoryDomainList

schemas/InventoryDomain

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/InventoryDomain"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
CsvImportRequest

{
  "type": "object",
  "required": [
    "csv"
  ],
  "properties": {
    "csv": {
      "type": "string",
      "minLength": 1,
      "description": "CSV document with a header row; see the operation summary for the accepted columns."
    },
    "dry_run": {
      "type": "boolean",
      "description": "Validate and report per-row outcomes without persisting."
    }
  }
}
CsvImportRowStatus

{
  "type": "string",
  "enum": [
    "would_create",
    "would_update",
    "created",
    "updated",
    "error"
  ],
  "x-enum-varnames": [
    "CsvImportRowStatusWouldCreate",
    "CsvImportRowStatusWouldUpdate",
    "CsvImportRowStatusCreated",
    "CsvImportRowStatusUpdated",
    "CsvImportRowStatusError"
  ]
}
CsvImportRow

schemas/CsvImportRowStatus

{
  "type": "object",
  "required": [
    "index",
    "status"
  ],
  "properties": {
    "index": {
      "type": "integer",
      "description": "1-based data-row position (header excluded)."
    },
    "key": {
      "type": "string",
      "description": "The row's upsert key (hostname / bundle_id)."
    },
    "status": {
      "$ref": "#/components/schemas/CsvImportRowStatus"
    },
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Created / updated resource id (not set for dry-run or error rows)."
    },
    "error": {
      "type": "string"
    }
  }
}
CsvImportResponse

schemas/CsvImportRow

{
  "type": "object",
  "required": [
    "rows"
  ],
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/CsvImportRow"
      }
    }
  }
}
StoreLookupRequest

{
  "type": "object",
  "required": [
    "store_url"
  ],
  "properties": {
    "store_url": {
      "type": "string",
      "format": "uri",
      "minLength": 1
    }
  }
}
StoreLookupSource

{
  "type": "string",
  "description": "url = only the URL was parsed (no public lookup API for that store); api = metadata fetched from the store's public lookup API.",
  "enum": [
    "url",
    "api"
  ],
  "x-enum-varnames": [
    "StoreLookupSourceUrl",
    "StoreLookupSourceApi"
  ]
}
StoreLookupResult

schemas/StoreLookupSource

{
  "type": "object",
  "required": [
    "store_url",
    "platform",
    "resolved",
    "source"
  ],
  "properties": {
    "store_url": {
      "type": "string"
    },
    "platform": {
      "type": "string",
      "description": "Platform catalog name (GET /v1/platforms); empty when the URL is not a recognised store."
    },
    "platform_id": {
      "type": "string",
      "format": "uuid"
    },
    "store_id": {
      "type": "string",
      "description": "Store-assigned numeric / slug id parsed from the URL."
    },
    "bundle_id": {
      "type": "string",
      "description": "Package / bundle identifier when the store exposes one."
    },
    "name": {
      "type": "string"
    },
    "developer": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "resolved": {
      "type": "boolean",
      "description": "True when name / bundle came back from the store API."
    },
    "source": {
      "$ref": "#/components/schemas/StoreLookupSource"
    }
  }
}
ApiKeyStatus

{
  "type": "string",
  "enum": [
    "ACTIVE",
    "REVOKED"
  ],
  "x-enum-varnames": [
    "ApiKeyStatusACTIVE",
    "ApiKeyStatusREVOKED"
  ]
}
ApiKey

schemas/ApiKeyStatus

{
  "type": "object",
  "description": "A tenant API key (api_key table). Only prefix (non-secret lookup handle) and the SHA-256 hash of the secret are stored; the secret itself is returned once by createApiKey.\n",
  "required": [
    "id",
    "tenant_id",
    "name",
    "prefix",
    "roles",
    "status",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "prefix": {
      "type": "string",
      "description": "Non-secret key handle (rt_key_<prefix>) shown in lists and audit."
    },
    "roles": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "authz.Role names the key grants (docs/spec/authz-roles.md)."
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Set for publisher-persona keys."
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid",
      "description": "Set for advertiser-persona keys."
    },
    "status": {
      "$ref": "#/components/schemas/ApiKeyStatus"
    },
    "last_used_at": {
      "type": "string",
      "format": "date-time"
    },
    "revoked_at": {
      "type": "string",
      "format": "date-time"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ApiKeyCreate

{
  "type": "object",
  "required": [
    "name",
    "roles"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "roles": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string"
      },
      "description": "Tenant-assignable roles only; operator is never grantable."
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid",
      "description": "Required when roles includes publisher."
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid",
      "description": "Required when roles includes advertiser."
    }
  }
}
ApiKeyCreated

schemas/ApiKey

{
  "description": "The created key plus its plaintext secret (returned once, at creation only).",
  "allOf": [
    {
      "$ref": "#/components/schemas/ApiKey"
    },
    {
      "type": "object",
      "required": [
        "secret"
      ],
      "properties": {
        "secret": {
          "type": "string",
          "description": "The full API key (send as X-Riptide-Api-Key). Shown once; never returned again."
        }
      }
    }
  ]
}
ApiKeyRotated

schemas/ApiKeyCreated

{
  "description": "The successor key (with its plaintext secret, returned once) plus the rotation lineage: the key it replaces and the instant that key stops authenticating.\n",
  "allOf": [
    {
      "$ref": "#/components/schemas/ApiKeyCreated"
    },
    {
      "type": "object",
      "required": [
        "rotated_from_id",
        "previous_expires_at",
        "grace"
      ],
      "properties": {
        "rotated_from_id": {
          "type": "string",
          "format": "uuid",
          "description": "The key this successor replaces; it keeps working until previous_expires_at."
        },
        "previous_expires_at": {
          "type": "string",
          "format": "date-time",
          "description": "When the previous key stops authenticating (rotation time + grace)."
        },
        "grace": {
          "type": "string",
          "description": "The applied grace as a duration string (e.g. `2h0m0s`)."
        }
      }
    }
  ]
}
ApiKeyList

schemas/ApiKey

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ApiKey"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
PublisherReportSummary

{
  "type": "object",
  "description": "Publisher portal dashboard read model. Money fields are decimal strings (4 dp) in the tenant reporting currency; counts are zero (executed=false) when no warehouse is wired.\n",
  "required": [
    "tenant_id",
    "publisher_id",
    "publisher_public_id",
    "from",
    "to",
    "requests",
    "impressions",
    "fills",
    "revenue_net",
    "publisher_payout",
    "executed"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid"
    },
    "publisher_public_id": {
      "type": "string"
    },
    "from": {
      "type": "string",
      "format": "date-time"
    },
    "to": {
      "type": "string",
      "format": "date-time"
    },
    "requests": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "fills": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "revenue_net": {
      "type": "string"
    },
    "publisher_payout": {
      "type": "string"
    },
    "currency": {
      "type": "string"
    },
    "executed": {
      "type": "boolean",
      "description": "False when the reporting warehouse is not configured (counts are then zero, not estimated)."
    }
  }
}
PublisherPayoutStatementStatus

{
  "type": "string",
  "enum": [
    "DRAFT",
    "ISSUED",
    "PAID",
    "VOID"
  ],
  "x-enum-varnames": [
    "PublisherPayoutStatementStatusDRAFT",
    "PublisherPayoutStatementStatusISSUED",
    "PublisherPayoutStatementStatusPAID",
    "PublisherPayoutStatementStatusVOID"
  ]
}
PublisherPayoutStatement

schemas/PublisherPayoutStatementStatus

{
  "type": "object",
  "description": "Publisher payout statement (SR-204 seam, docs/design/publisher-persona.md): the publisher_payout leg of the reporting layer aggregated over one period, plus a signed adjustment. total_due = publisher_share + adjustments. Money is decimal strings (4 dp).\n",
  "required": [
    "id",
    "tenant_id",
    "publisher_id",
    "period_start",
    "period_end",
    "currency",
    "impressions",
    "gross_revenue",
    "publisher_share",
    "adjustments",
    "total_due",
    "status",
    "provider",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "publisher_id": {
      "type": "string",
      "format": "uuid"
    },
    "period_start": {
      "type": "string",
      "format": "date",
      "description": "Inclusive."
    },
    "period_end": {
      "type": "string",
      "format": "date",
      "description": "Exclusive."
    },
    "currency": {
      "type": "string"
    },
    "impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "gross_revenue": {
      "type": "string",
      "description": "Tenant net revenue on this publisher's supply over the period."
    },
    "publisher_share": {
      "type": "string",
      "description": "Publisher-payable amount from the fee schedule (publisher_payout)."
    },
    "adjustments": {
      "type": "string",
      "description": "Signed manual adjustment."
    },
    "total_due": {
      "type": "string"
    },
    "status": {
      "$ref": "#/components/schemas/PublisherPayoutStatementStatus"
    },
    "provider": {
      "type": "string",
      "description": "Payout provider the statement was issued through (e.g. manual)."
    },
    "provider_ref": {
      "type": "string",
      "description": "Payout provider's reference for the transfer (SR-1238a); empty until handed to the provider."
    },
    "provider_status": {
      "type": "string",
      "readOnly": true,
      "description": "Provider-reported transfer state as last synced (SR-1238a); empty until handed to the provider."
    },
    "notes": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
PublisherPayoutStatementGenerate

{
  "type": "object",
  "required": [
    "period_start",
    "period_end"
  ],
  "properties": {
    "period_start": {
      "type": "string",
      "format": "date"
    },
    "period_end": {
      "type": "string",
      "format": "date",
      "description": "Exclusive; must be after period_start."
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3
    },
    "adjustments": {
      "type": "string",
      "description": "Signed decimal string (4 dp); omitted = 0."
    },
    "notes": {
      "type": "string"
    }
  }
}
PublisherPayoutStatementList

schemas/PublisherPayoutStatement

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PublisherPayoutStatement"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
TenantCells

{
  "type": "object",
  "description": "A tenant's cell assignment (tenant_cell; SR-1221, design 16 \"Tenant->cell routing seam\").",
  "required": [
    "tenant_id",
    "home_cell_id",
    "serving_cell_ids"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "home_cell_id": {
      "type": "string",
      "description": "Cell owning the tenant's control-plane residency (role home)."
    },
    "serving_cell_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Every cell whose plan carries the tenant (home included), sorted."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
TenantCellsUpdate

{
  "type": "object",
  "required": [
    "home_cell_id"
  ],
  "properties": {
    "home_cell_id": {
      "type": "string",
      "minLength": 1
    },
    "serving_cell_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "Replaces the serving set; the home cell is added when omitted. Omitted = home only."
    }
  }
}
TenantCellRef

schemas/TenantCellRole

{
  "type": "object",
  "required": [
    "tenant_id",
    "role"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "role": {
      "$ref": "#/components/schemas/TenantCellRole"
    }
  }
}
TenantCellRole

{
  "type": "string",
  "description": "tenant_cell.role — `home` (control-plane residency, also serving) or `serving`.",
  "enum": [
    "home",
    "serving"
  ],
  "x-enum-varnames": [
    "TenantCellRoleHome",
    "TenantCellRoleServing"
  ]
}
TenantCellRefList

schemas/TenantCellRef

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/TenantCellRef"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ApprovalStatus

{
  "type": "string",
  "description": "Partner approval state for an app bundle or a site domain (SR-1218).",
  "enum": [
    "PENDING",
    "APPROVED",
    "REJECTED"
  ],
  "x-enum-varnames": [
    "ApprovalStatusPENDING",
    "ApprovalStatusAPPROVED",
    "ApprovalStatusREJECTED"
  ]
}
DomainApproval

schemas/ApprovalStatus

{
  "type": "object",
  "description": "One site-domain approval for a demand partner (demand_partner_domain_approval; SR-1218).",
  "required": [
    "tenant_id",
    "demand_partner_id",
    "domain",
    "status"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "demand_partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "domain": {
      "type": "string",
      "description": "Lower-case site domain, no scheme."
    },
    "status": {
      "$ref": "#/components/schemas/ApprovalStatus"
    },
    "note": {
      "type": "string"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
DomainApprovalUpdate

schemas/ApprovalStatus

{
  "type": "object",
  "required": [
    "status"
  ],
  "properties": {
    "status": {
      "$ref": "#/components/schemas/ApprovalStatus"
    },
    "note": {
      "type": "string",
      "maxLength": 1024,
      "description": "Free-text reason; an empty string clears it."
    }
  }
}
DomainApprovalList

schemas/DomainApproval

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/DomainApproval"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ApprovalStatusCounts

{
  "type": "object",
  "required": [
    "pending",
    "approved",
    "rejected"
  ],
  "properties": {
    "pending": {
      "type": "integer",
      "format": "int64"
    },
    "approved": {
      "type": "integer",
      "format": "int64"
    },
    "rejected": {
      "type": "integer",
      "format": "int64"
    }
  }
}
ApprovalCounts

schemas/ApprovalStatusCounts

{
  "type": "object",
  "description": "Per-partner approval counts (SR-1218) — app bundles (App.route_approvals) and site domains.",
  "required": [
    "demand_partner_id",
    "approvals_required",
    "bundles",
    "domains"
  ],
  "properties": {
    "demand_partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "approvals_required": {
      "type": "boolean",
      "description": "Mirrors DemandPartner.approvals_required: whether the gate is blocking."
    },
    "bundles": {
      "$ref": "#/components/schemas/ApprovalStatusCounts"
    },
    "domains": {
      "$ref": "#/components/schemas/ApprovalStatusCounts"
    }
  }
}
CrawlerConfig

{
  "type": "object",
  "description": "ads.txt / app-ads.txt crawler tunables (crawler_config; SR-1212). The platform defaults apply until a row is written.",
  "required": [
    "tenant_id",
    "http_fallback",
    "redirect_hop_cap",
    "fetch_timeout_seconds",
    "batch_size",
    "recrawl_after_hours",
    "app_ads_discovery"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "http_fallback": {
      "type": "boolean",
      "description": "Retry over plain HTTP when the HTTPS fetch fails (default true)."
    },
    "redirect_hop_cap": {
      "type": "integer",
      "minimum": 0,
      "maximum": 20,
      "description": "In-root-only redirects followed before the crawl gives up (default 5)."
    },
    "fetch_timeout_seconds": {
      "type": "integer",
      "minimum": 1,
      "maximum": 600,
      "description": "Per-document fetch timeout (default 180)."
    },
    "batch_size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "Domains crawled per batch (default 5)."
    },
    "recrawl_after_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 720,
      "description": "A domain crawled within this window is skipped unless recrawl is forced (default 24)."
    },
    "app_ads_discovery": {
      "type": "boolean",
      "description": "Discover app-ads.txt from the store listing's developer site (default true)."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
CrawlerConfigUpdate

{
  "type": "object",
  "description": "Partial update by presence — an omitted field keeps its current (or default) value.",
  "properties": {
    "http_fallback": {
      "type": "boolean"
    },
    "redirect_hop_cap": {
      "type": "integer",
      "minimum": 0,
      "maximum": 20
    },
    "fetch_timeout_seconds": {
      "type": "integer",
      "minimum": 1,
      "maximum": 600
    },
    "batch_size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "recrawl_after_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 720
    },
    "app_ads_discovery": {
      "type": "boolean"
    }
  }
}
PartnerSellersImportStatus

{
  "type": "string",
  "enum": [
    "PENDING",
    "RUNNING",
    "SUCCEEDED",
    "FAILED"
  ],
  "x-enum-varnames": [
    "PartnerSellersImportStatusPENDING",
    "PartnerSellersImportStatusRUNNING",
    "PartnerSellersImportStatusSUCCEEDED",
    "PartnerSellersImportStatusFAILED"
  ]
}
SellersImportRowCompliance

{
  "type": "string",
  "description": "Cross-check verdict for one seller row (sellers.json 1.0 name / domain conditional requirements, confidential flag, passthrough resolution).",
  "enum": [
    "compliant",
    "missing_name",
    "missing_domain",
    "confidential_conflict",
    "passthrough_unresolved"
  ],
  "x-enum-varnames": [
    "SellersImportRowComplianceCompliant",
    "SellersImportRowComplianceMissingName",
    "SellersImportRowComplianceMissingDomain",
    "SellersImportRowComplianceConfidentialConflict",
    "SellersImportRowCompliancePassthroughUnresolved"
  ]
}
SellersImportSellerType

{
  "type": "string",
  "enum": [
    "PUBLISHER",
    "INTERMEDIARY",
    "BOTH"
  ],
  "x-enum-varnames": [
    "SellersImportSellerTypePUBLISHER",
    "SellersImportSellerTypeINTERMEDIARY",
    "SellersImportSellerTypeBOTH"
  ]
}
PartnerSellersImportRow

schemas/SellersImportSellerTypeschemas/SellersImportRowCompliance

{
  "type": "object",
  "required": [
    "seller_id",
    "seller_type",
    "compliance"
  ],
  "properties": {
    "seller_id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "domain": {
      "type": "string"
    },
    "seller_type": {
      "$ref": "#/components/schemas/SellersImportSellerType"
    },
    "is_confidential": {
      "type": "boolean"
    },
    "is_passthrough": {
      "type": "boolean"
    },
    "compliance": {
      "$ref": "#/components/schemas/SellersImportRowCompliance"
    }
  }
}
PartnerSellersImport

schemas/PartnerSellersImportStatusschemas/PartnerSellersImportRow

{
  "type": "object",
  "description": "One import of a demand partner's sellers.json (partner_sellers_import; SR-1212).",
  "required": [
    "id",
    "tenant_id",
    "demand_partner_id",
    "source_url",
    "status",
    "row_count",
    "compliant_count",
    "noncompliant_count",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "demand_partner_id": {
      "type": "string",
      "format": "uuid"
    },
    "source_url": {
      "type": "string",
      "format": "uri"
    },
    "status": {
      "$ref": "#/components/schemas/PartnerSellersImportStatus"
    },
    "fetched_at": {
      "type": "string",
      "format": "date-time"
    },
    "row_count": {
      "type": "integer"
    },
    "compliant_count": {
      "type": "integer"
    },
    "noncompliant_count": {
      "type": "integer"
    },
    "error_text": {
      "type": "string"
    },
    "rows": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PartnerSellersImportRow"
      },
      "description": "Present on getPartnerSellersImport only."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
PartnerSellersImportList

schemas/PartnerSellersImport

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/PartnerSellersImport"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
PartnerSellersImportRunRequest

{
  "type": "object",
  "required": [
    "source_url"
  ],
  "properties": {
    "source_url": {
      "type": "string",
      "format": "uri",
      "minLength": 12,
      "description": "HTTPS URL of the partner's sellers.json."
    }
  }
}
ContentProgram

{
  "type": "object",
  "description": "One program-guide entry (content_program; riptide.content.v1.Program; SR-1213).",
  "required": [
    "id",
    "tenant_id",
    "provider",
    "external_id",
    "title",
    "genres",
    "keywords",
    "live",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid"
    },
    "provider": {
      "type": "string",
      "description": "Guide source the row came from (feed id, EPG vendor key, or manual)."
    },
    "external_id": {
      "type": "string",
      "description": "The provider's own program identifier; unique with provider per tenant."
    },
    "title": {
      "type": "string"
    },
    "series": {
      "type": "string"
    },
    "season": {
      "type": "string"
    },
    "episode": {
      "type": "string"
    },
    "genres": {
      "type": "array",
      "maxItems": 64,
      "items": {
        "type": "string",
        "maxLength": 64
      },
      "description": "Content Taxonomy 3.1 ids, sorted."
    },
    "keywords": {
      "type": "array",
      "maxItems": 256,
      "items": {
        "type": "string",
        "maxLength": 128
      },
      "description": "Lower-case keywords, sorted."
    },
    "rating": {
      "type": "string"
    },
    "language": {
      "type": "string",
      "description": "ISO 639-1 code."
    },
    "duration_seconds": {
      "type": "integer",
      "minimum": 0
    },
    "channel": {
      "type": "string",
      "description": "Linear channel key; empty for VOD."
    },
    "air_start": {
      "type": "string",
      "format": "date-time"
    },
    "air_end": {
      "type": "string",
      "format": "date-time"
    },
    "live": {
      "type": "boolean"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
ContentProgramCreate

{
  "type": "object",
  "required": [
    "provider",
    "external_id",
    "title"
  ],
  "properties": {
    "provider": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "external_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512
    },
    "series": {
      "type": "string",
      "maxLength": 512
    },
    "season": {
      "type": "string",
      "maxLength": 64
    },
    "episode": {
      "type": "string",
      "maxLength": 64
    },
    "genres": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "keywords": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "rating": {
      "type": "string",
      "maxLength": 32
    },
    "language": {
      "type": "string",
      "minLength": 2,
      "maxLength": 2
    },
    "duration_seconds": {
      "type": "integer",
      "minimum": 0
    },
    "channel": {
      "type": "string",
      "maxLength": 128,
      "description": "Requires air_start / air_end."
    },
    "air_start": {
      "type": "string",
      "format": "date-time"
    },
    "air_end": {
      "type": "string",
      "format": "date-time"
    },
    "live": {
      "type": "boolean"
    }
  }
}
ContentProgramUpdate

{
  "type": "object",
  "description": "Partial update by presence; arrays present replace the whole set. provider / external_id are immutable.",
  "properties": {
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512
    },
    "series": {
      "type": "string",
      "maxLength": 512
    },
    "season": {
      "type": "string",
      "maxLength": 64
    },
    "episode": {
      "type": "string",
      "maxLength": 64
    },
    "genres": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "keywords": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "rating": {
      "type": "string",
      "maxLength": 32
    },
    "language": {
      "type": "string",
      "minLength": 2,
      "maxLength": 2
    },
    "duration_seconds": {
      "type": "integer",
      "minimum": 0
    },
    "channel": {
      "type": "string",
      "maxLength": 128
    },
    "air_start": {
      "type": "string",
      "format": "date-time"
    },
    "air_end": {
      "type": "string",
      "format": "date-time"
    },
    "live": {
      "type": "boolean"
    }
  }
}
ContentProgramList

schemas/ContentProgram

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ContentProgram"
      }
    },
    "next_cursor": {
      "type": "string"
    }
  }
}
ContentDictionaryEntry

{
  "type": "object",
  "required": [
    "value",
    "count"
  ],
  "properties": {
    "value": {
      "type": "string"
    },
    "count": {
      "type": "integer",
      "format": "int64",
      "description": "Programs carrying the value."
    }
  }
}
ContentDictionary

schemas/ContentDictionaryEntry

{
  "type": "object",
  "description": "Distinct values across the tenant's program guide with program counts (SR-1213 dictionary endpoint).",
  "required": [
    "genres",
    "keywords",
    "providers",
    "channels"
  ],
  "properties": {
    "genres": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ContentDictionaryEntry"
      }
    },
    "keywords": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ContentDictionaryEntry"
      }
    },
    "providers": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ContentDictionaryEntry"
      }
    },
    "channels": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ContentDictionaryEntry"
      }
    }
  }
}
PublicBranding

{
  "type": "object",
  "description": "The pre-auth subset of Branding a console host may show (getPublicBranding); never hostnames.",
  "properties": {
    "ad_system_name": {
      "type": "string",
      "description": "Product / brand name shown on the login and verify pages."
    },
    "logo_url": {
      "type": "string",
      "description": "HTTPS URL of the logo."
    },
    "favicon_url": {
      "type": "string",
      "description": "HTTPS URL of the favicon."
    },
    "primary_color": {
      "type": "string",
      "pattern": "^#[0-9a-fA-F]{6}$",
      "description": "Primary brand colour (#rrggbb)."
    },
    "accent_color": {
      "type": "string",
      "pattern": "^#[0-9a-fA-F]{6}$",
      "description": "Accent brand colour (#rrggbb)."
    }
  }
}
ListingProposalList

schemas/ListingProposal

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "description": "The page of proposal party rows.",
      "items": {
        "$ref": "#/components/schemas/ListingProposal"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor for the next page; absent on the last page."
    }
  }
}
AudienceOrigin

{
  "type": "string",
  "description": "How an audience came to exist — MANUAL (created in the console / API), IMPORTED (from a list import), ACTIVATED (bound by a marketplace signal activation), EVENT_MEMBERSHIP (built from event memberships).",
  "enum": [
    "MANUAL",
    "IMPORTED",
    "ACTIVATED",
    "EVENT_MEMBERSHIP"
  ],
  "x-enum-varnames": [
    "AudienceOriginMANUAL",
    "AudienceOriginIMPORTED",
    "AudienceOriginACTIVATED",
    "AudienceOriginEVENTMEMBERSHIP"
  ]
}
EntityUsage

{
  "type": "object",
  "description": "Reference counts for a reusable entity (REM-J \"Used by\").",
  "required": [
    "line_items",
    "creatives",
    "placements"
  ],
  "properties": {
    "line_items": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Line items referencing the entity."
    },
    "creatives": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Creatives referencing the entity."
    },
    "placements": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Placements referencing the entity."
    }
  }
}
RetentionTier

{
  "type": "string",
  "description": "Event retention tier (Event.retention_tier); the event store's TTL is kind × tier.",
  "enum": [
    "basic",
    "standard",
    "extended"
  ],
  "x-enum-varnames": [
    "RetentionTierBasic",
    "RetentionTierStandard",
    "RetentionTierExtended"
  ]
}
ReportConfigScheduleCreate

schemas/ScheduledReportCadence

{
  "type": "object",
  "description": "Schedule requested alongside a new report config (SR-1233); ScheduledReportCreate minus report_config_id, which is the config being created.",
  "required": [
    "cadence",
    "destination_url"
  ],
  "properties": {
    "cadence": {
      "$ref": "#/components/schemas/ScheduledReportCadence"
    },
    "destination_url": {
      "type": "string",
      "format": "uri",
      "minLength": 1,
      "description": "Delivery destination; see ScheduledReport.destination_url."
    }
  }
}
ReportConfigSchedule

schemas/ScheduledReportCadence

{
  "type": "object",
  "description": "The scheduled delivery attached to a report config (SR-1233).",
  "required": [
    "scheduled_report_id",
    "cadence",
    "destination_url"
  ],
  "properties": {
    "scheduled_report_id": {
      "type": "string",
      "format": "uuid",
      "description": "The ScheduledReport row; manage it through the scheduled-reports operations."
    },
    "cadence": {
      "$ref": "#/components/schemas/ScheduledReportCadence"
    },
    "destination_url": {
      "type": "string",
      "format": "uri",
      "description": "Delivery destination; see ScheduledReport.destination_url."
    },
    "next_run_at": {
      "type": "string",
      "format": "date-time",
      "description": "Next delivery instant."
    },
    "destination_secret": {
      "type": "string",
      "description": "HMAC signing secret — present exactly once, on the createReportConfig response that created the schedule; never on a GET."
    }
  }
}
InvoiceStatus

{
  "type": "string",
  "description": "Invoice lifecycle (design 41) — DRAFT (open, lines accumulate), REVIEW (frozen for approval), ISSUED (numbered, sent, dunning active), PAID, VOID.",
  "enum": [
    "DRAFT",
    "REVIEW",
    "ISSUED",
    "PAID",
    "VOID"
  ],
  "x-enum-varnames": [
    "InvoiceStatusDRAFT",
    "InvoiceStatusREVIEW",
    "InvoiceStatusISSUED",
    "InvoiceStatusPAID",
    "InvoiceStatusVOID"
  ]
}
InvoiceDocumentFormat

{
  "type": "string",
  "description": "Rendered statement format.",
  "enum": [
    "html",
    "pdf"
  ],
  "x-enum-varnames": [
    "InvoiceDocumentFormatHtml",
    "InvoiceDocumentFormatPdf"
  ]
}
FxSnapshot

{
  "type": "object",
  "description": "FX rates frozen on an invoice at ISSUED.",
  "required": [
    "as_of",
    "base_currency",
    "rates"
  ],
  "properties": {
    "as_of": {
      "type": "string",
      "format": "date-time",
      "description": "Instant the rates were taken."
    },
    "base_currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3,
      "description": "Invoice currency the rates convert into."
    },
    "rates": {
      "type": "object",
      "description": "Source currency → decimal rate into base_currency.",
      "additionalProperties": {
        "type": "string"
      }
    }
  }
}
InvoiceTax

{
  "type": "object",
  "description": "Tax line computed through the tax seam at ISSUED.",
  "required": [
    "jurisdiction",
    "rate",
    "amount"
  ],
  "properties": {
    "jurisdiction": {
      "type": "string",
      "description": "Tax jurisdiction key the seam resolved."
    },
    "rate": {
      "type": "string",
      "description": "Decimal rate (e.g. 0.2000 for 20%)."
    },
    "amount": {
      "type": "string",
      "description": "Decimal tax amount in the invoice currency."
    }
  }
}
InvoiceTransitionRequest

schemas/InvoiceStatus

{
  "type": "object",
  "required": [
    "to",
    "reason"
  ],
  "properties": {
    "to": {
      "$ref": "#/components/schemas/InvoiceStatus"
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Recorded in the audit envelope."
    }
  }
}
InvoiceCredit

{
  "type": "object",
  "description": "A credit recorded against an invoice.",
  "required": [
    "id",
    "invoice_id",
    "amount",
    "currency",
    "reason",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Credit id."
    },
    "invoice_id": {
      "type": "string",
      "format": "uuid",
      "description": "The invoice credited."
    },
    "amount": {
      "type": "string",
      "description": "Positive decimal amount in the invoice currency."
    },
    "currency": {
      "type": "string",
      "description": "Invoice currency."
    },
    "reason": {
      "type": "string",
      "description": "Why the credit was granted."
    },
    "created_by": {
      "type": "string",
      "description": "Actor label of who recorded it."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When it was recorded."
    }
  }
}
InvoiceCreditCreate

{
  "type": "object",
  "required": [
    "amount",
    "reason"
  ],
  "properties": {
    "amount": {
      "type": "string",
      "pattern": "^[0-9]+(\\.[0-9]{1,4})?$",
      "description": "Positive decimal amount in the invoice currency (4 dp)."
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Why the credit is granted; audited."
    }
  }
}
InvoiceAdjustment

{
  "type": "object",
  "description": "A signed adjustment line on an invoice.",
  "required": [
    "id",
    "invoice_id",
    "amount",
    "currency",
    "description",
    "reason",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Adjustment id."
    },
    "invoice_id": {
      "type": "string",
      "format": "uuid",
      "description": "The invoice adjusted."
    },
    "amount": {
      "type": "string",
      "description": "Signed decimal amount in the invoice currency."
    },
    "currency": {
      "type": "string",
      "description": "Invoice currency."
    },
    "description": {
      "type": "string",
      "description": "Line text shown on the statement."
    },
    "reason": {
      "type": "string",
      "description": "Why the adjustment was made."
    },
    "created_by": {
      "type": "string",
      "description": "Actor label of who recorded it."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When it was recorded."
    }
  }
}
InvoiceAdjustmentCreate

{
  "type": "object",
  "required": [
    "amount",
    "description",
    "reason"
  ],
  "properties": {
    "amount": {
      "type": "string",
      "pattern": "^-?[0-9]+(\\.[0-9]{1,4})?$",
      "description": "Signed decimal amount in the invoice currency (4 dp); non-zero."
    },
    "description": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500,
      "description": "Line text shown on the statement."
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Why the adjustment is made; audited."
    }
  }
}
DunningState

{
  "type": "object",
  "description": "Collection state of an ISSUED invoice.",
  "required": [
    "tenant_id",
    "invoice_id",
    "attempts"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "The billed tenant."
    },
    "invoice_id": {
      "type": "string",
      "format": "uuid",
      "description": "The invoice in dunning."
    },
    "attempts": {
      "type": "integer",
      "minimum": 0,
      "description": "Charge attempts made so far."
    },
    "next_attempt_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the next charge retry runs; null when dunning is exhausted or the invoice left ISSUED."
    },
    "suspended_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When serving was suspended for non-payment; null while not suspended."
    }
  }
}
Invoice

schemas/InvoiceStatusschemas/InvoiceTotalsschemas/InvoiceProofOfPerformance

{
  "type": "object",
  "description": "An invoice the tenant issued to one of its advertisers (SR-1238a tenant-to-customer billing; D67).",
  "required": [
    "id",
    "tenant_id",
    "advertiser_id",
    "period_start",
    "period_end",
    "status",
    "currency",
    "totals"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Invoice id."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Issuing tenant."
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid",
      "description": "Billed advertiser."
    },
    "campaign_order_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The order billed when the invoice covers one order; null for a period invoice across orders."
    },
    "period_start": {
      "type": "string",
      "format": "date",
      "description": "Inclusive."
    },
    "period_end": {
      "type": "string",
      "format": "date",
      "description": "Exclusive."
    },
    "status": {
      "$ref": "#/components/schemas/InvoiceStatus"
    },
    "number": {
      "type": "string",
      "nullable": true,
      "description": "Sequential number assigned at ISSUED; null before."
    },
    "currency": {
      "type": "string",
      "description": "Invoice currency."
    },
    "totals": {
      "$ref": "#/components/schemas/InvoiceTotals"
    },
    "proof_of_performance": {
      "description": "Delivery evidence the invoice is based on.",
      "allOf": [
        {
          "$ref": "#/components/schemas/InvoiceProofOfPerformance"
        }
      ]
    },
    "issued_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the invoice became ISSUED; null before."
    },
    "paid_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the invoice became PAID; null otherwise."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "Row creation."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "description": "Last change."
    }
  }
}
InvoiceTotals

{
  "type": "object",
  "description": "Money on an advertiser invoice (decimal strings, 4 dp).",
  "required": [
    "subtotal",
    "tax",
    "credits",
    "adjustments",
    "total"
  ],
  "properties": {
    "subtotal": {
      "type": "string",
      "description": "Sum of the delivery lines."
    },
    "tax": {
      "type": "string",
      "description": "Tax on the subtotal."
    },
    "credits": {
      "type": "string",
      "description": "Credits applied (non-negative; subtracted)."
    },
    "adjustments": {
      "type": "string",
      "description": "Signed adjustments applied."
    },
    "total": {
      "type": "string",
      "description": "subtotal + tax + adjustments − credits."
    }
  }
}
InvoiceProofOfPerformance

schemas/InvoiceProofLine

{
  "type": "object",
  "description": "Per-line delivery evidence behind an advertiser invoice.",
  "required": [
    "impressions",
    "clicks",
    "lines"
  ],
  "properties": {
    "impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Billable impressions in the period."
    },
    "clicks": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Clicks in the period."
    },
    "completed_views": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Completed video views in the period."
    },
    "lines": {
      "type": "array",
      "description": "One row per line item billed.",
      "items": {
        "$ref": "#/components/schemas/InvoiceProofLine"
      }
    }
  }
}
InvoiceProofLine

{
  "type": "object",
  "required": [
    "line_item_id",
    "impressions",
    "amount"
  ],
  "properties": {
    "line_item_id": {
      "type": "string",
      "format": "uuid",
      "description": "The line item."
    },
    "impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Billable impressions."
    },
    "clicks": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Clicks."
    },
    "amount": {
      "type": "string",
      "description": "Decimal amount billed for the line."
    }
  }
}
InvoiceList

schemas/Invoice

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "description": "The page of advertiser invoices.",
      "items": {
        "$ref": "#/components/schemas/Invoice"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor for the next page; absent on the last page."
    }
  }
}
WalletBinding

{
  "type": "object",
  "description": "Advertiser → prepaid wallet binding (SR-1238a).",
  "required": [
    "tenant_id",
    "advertiser_id",
    "wallet_id",
    "auto_pause"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning tenant."
    },
    "advertiser_id": {
      "type": "string",
      "format": "uuid",
      "description": "The advertiser."
    },
    "wallet_id": {
      "type": "string",
      "format": "uuid",
      "description": "The prepaid wallet (prepaid ledger account) the advertiser's delivery draws down."
    },
    "auto_pause": {
      "type": "boolean",
      "description": "Pause the advertiser's line items when the wallet balance reaches zero and resume on top-up."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "Row creation."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "description": "Last change."
    }
  }
}
WalletBindingSet

{
  "type": "object",
  "required": [
    "wallet_id"
  ],
  "properties": {
    "wallet_id": {
      "type": "string",
      "format": "uuid",
      "description": "The prepaid wallet to bind."
    },
    "auto_pause": {
      "type": "boolean",
      "default": false,
      "description": "See WalletBinding.auto_pause."
    }
  }
}
WalletBindingList

schemas/WalletBinding

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "description": "The page of bindings.",
      "items": {
        "$ref": "#/components/schemas/WalletBinding"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor for the next page; absent on the last page."
    }
  }
}
SettlementRunStatus

{
  "type": "string",
  "description": "State of a settlement run.",
  "enum": [
    "PENDING",
    "RUNNING",
    "COMPLETED",
    "FAILED"
  ],
  "x-enum-varnames": [
    "SettlementRunStatusPENDING",
    "SettlementRunStatusRUNNING",
    "SettlementRunStatusCOMPLETED",
    "SettlementRunStatusFAILED"
  ]
}
SettlementTotals

{
  "type": "object",
  "description": "Money folded by a settlement run (decimal strings, 4 dp).",
  "required": [
    "currency",
    "gross",
    "fees",
    "net"
  ],
  "properties": {
    "currency": {
      "type": "string",
      "description": "Settlement currency (the tenant's settlement_currency)."
    },
    "gross": {
      "type": "string",
      "description": "Gross payable before fees."
    },
    "fees": {
      "type": "string",
      "description": "Fees withheld."
    },
    "net": {
      "type": "string",
      "description": "Net handed to the payout provider."
    }
  }
}
VendorSettlementRunRequest

{
  "type": "object",
  "required": [
    "period"
  ],
  "properties": {
    "period": {
      "type": "string",
      "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$",
      "description": "Calendar month to settle (YYYY-MM)."
    }
  }
}
VendorSettlementRun

schemas/SettlementRunStatusschemas/SettlementTotals

{
  "type": "object",
  "description": "One vendor settlement run (SR-1238a payout provider).",
  "required": [
    "id",
    "tenant_id",
    "period",
    "status",
    "totals"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Run id."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning tenant."
    },
    "period": {
      "type": "string",
      "description": "Calendar month settled (YYYY-MM)."
    },
    "status": {
      "$ref": "#/components/schemas/SettlementRunStatus"
    },
    "totals": {
      "$ref": "#/components/schemas/SettlementTotals"
    },
    "statements": {
      "type": "integer",
      "minimum": 0,
      "description": "Publisher payout statements folded into the run."
    },
    "ran_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the run finished; null while PENDING / RUNNING."
    },
    "error": {
      "type": "string",
      "nullable": true,
      "description": "Provider or fold error when FAILED; null otherwise."
    }
  }
}
PaymentProviderEvent

{
  "type": "object",
  "description": "A payment-provider event as the provider posts it. The adapter registered for the path's `{provider}` maps the provider's own shape onto (external_id, kind, invoice reference, amount, currency, received_at); the fields below are the adapter-neutral minimum and the raw body is kept (payload_sha256) for audit.\n",
  "additionalProperties": true,
  "properties": {
    "id": {
      "type": "string",
      "description": "Provider event id (external_id); the dedup key with the provider."
    },
    "type": {
      "type": "string",
      "description": "Provider event type the adapter maps to a payment_event kind."
    }
  }
}
PaymentWebhookAck

{
  "type": "object",
  "required": [
    "received",
    "duplicate"
  ],
  "properties": {
    "received": {
      "type": "boolean",
      "description": "Always true on 200."
    },
    "duplicate": {
      "type": "boolean",
      "description": "True when the (provider, external_id) event had already been recorded; nothing was applied."
    },
    "payment_event_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "The payment_event row recorded (or previously recorded); null when the event kind is ignored by the adapter."
    }
  }
}
ForecastAdjustments

{
  "type": "object",
  "description": "Multiplicative adjustments (decimal strings in [0, 1]) applied to raw capacity in forecast v2.",
  "required": [
    "fill",
    "ivt",
    "viewability"
  ],
  "properties": {
    "fill": {
      "type": "string",
      "description": "Expected fill rate of the sampled requests."
    },
    "ivt": {
      "type": "string",
      "description": "Share retained after invalid-traffic filtering (1 − IVT rate)."
    },
    "viewability": {
      "type": "string",
      "description": "Expected viewable share (applies to viewable-impression goals only)."
    }
  }
}
ForecastContention

schemas/PriorityClass

{
  "type": "object",
  "description": "One booking overlapping the proposal in forecast v2.",
  "required": [
    "ref",
    "priority_class",
    "overlap",
    "contended_impressions"
  ],
  "properties": {
    "ref": {
      "type": "string",
      "description": "Booking ref (ForecastBooking.ref)."
    },
    "priority_class": {
      "$ref": "#/components/schemas/PriorityClass"
    },
    "overlap": {
      "type": "string",
      "description": "Share of the proposal's sampled requests the booking also targets (decimal in [0, 1])."
    },
    "contended_impressions": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Impressions the booking takes from the proposal's available capacity."
    }
  }
}
MarketplaceSettlementStatus

{
  "type": "string",
  "description": "State of a marketplace settlement row.",
  "enum": [
    "PENDING",
    "SETTLED",
    "DISPUTED",
    "VOID"
  ],
  "x-enum-varnames": [
    "MarketplaceSettlementStatusPENDING",
    "MarketplaceSettlementStatusSETTLED",
    "MarketplaceSettlementStatusDISPUTED",
    "MarketplaceSettlementStatusVOID"
  ]
}
MarketplaceSettlement

schemas/MarketplaceSettlementStatus

{
  "type": "object",
  "description": "What the tenant owes or is owed for one listing and counterparty in a period, from the path receipts (SR-1238b).",
  "required": [
    "id",
    "tenant_id",
    "period",
    "listing_id",
    "counterparty_tenant_id",
    "currency",
    "gross",
    "fees",
    "net",
    "status"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Settlement id."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning tenant."
    },
    "period": {
      "type": "string",
      "description": "Calendar month (YYYY-MM)."
    },
    "listing_id": {
      "type": "string",
      "format": "uuid",
      "description": "The marketplace listing."
    },
    "counterparty_tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "The other party (listing owner or activating buyer)."
    },
    "currency": {
      "type": "string",
      "description": "Settlement currency."
    },
    "gross": {
      "type": "string",
      "description": "Signed gross amount (positive = owed to the tenant)."
    },
    "fees": {
      "type": "object",
      "description": "Fee name → decimal amount withheld (marketplace, platform, ...).",
      "additionalProperties": {
        "type": "string"
      }
    },
    "net": {
      "type": "string",
      "description": "Signed net after fees."
    },
    "status": {
      "$ref": "#/components/schemas/MarketplaceSettlementStatus"
    },
    "receipts": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Path receipts folded into the row."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "Row creation."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "description": "Last change."
    }
  }
}
MarketplaceSettlementList

schemas/MarketplaceSettlement

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "description": "The page of settlements.",
      "items": {
        "$ref": "#/components/schemas/MarketplaceSettlement"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor for the next page; absent on the last page."
    }
  }
}
MarketplaceSettlementRunRequest

{
  "type": "object",
  "required": [
    "period"
  ],
  "properties": {
    "period": {
      "type": "string",
      "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$",
      "description": "Calendar month to settle (YYYY-MM)."
    }
  }
}
MarketplaceSettlementRun

schemas/SettlementRunStatus

{
  "type": "object",
  "description": "Summary of one marketplace settlement run.",
  "required": [
    "tenant_id",
    "period",
    "status",
    "settlements"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning tenant."
    },
    "period": {
      "type": "string",
      "description": "Calendar month settled (YYYY-MM)."
    },
    "status": {
      "$ref": "#/components/schemas/SettlementRunStatus"
    },
    "settlements": {
      "type": "integer",
      "minimum": 0,
      "description": "Settlement rows written or updated by the run."
    },
    "receipts": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Path receipts consumed by the run."
    },
    "ran_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the run finished; null while PENDING / RUNNING."
    }
  }
}
AgentBand

{
  "type": "string",
  "description": "Autonomy ladder band (design 20; proto agent.v1 AutonomyLevel) — RECOMMEND (proposes only), EXECUTE_WITHIN_BAND (acts within caps), CROSS_SURFACE (acts across surfaces), AGENT_TO_AGENT (may delegate to other agents).",
  "enum": [
    "RECOMMEND",
    "EXECUTE_WITHIN_BAND",
    "CROSS_SURFACE",
    "AGENT_TO_AGENT"
  ],
  "x-enum-varnames": [
    "AgentBandRECOMMEND",
    "AgentBandEXECUTEWITHINBAND",
    "AgentBandCROSSSURFACE",
    "AgentBandAGENTTOAGENT"
  ]
}
AgentWriteDefault

{
  "type": "string",
  "description": "The state an agent's newly created deliverable entities start in (SR-1239a governance by default) — DRAFT, PAUSED or ACTIVE (live immediately; requires the identity to be on EXECUTE_WITHIN_BAND or above).",
  "enum": [
    "DRAFT",
    "PAUSED",
    "ACTIVE"
  ],
  "x-enum-varnames": [
    "AgentWriteDefaultDRAFT",
    "AgentWriteDefaultPAUSED",
    "AgentWriteDefaultACTIVE"
  ]
}
AgentKeyAlg

{
  "type": "string",
  "description": "Signature algorithm of an agent identity key.",
  "enum": [
    "ED25519",
    "ES256"
  ],
  "x-enum-varnames": [
    "AgentKeyAlgED25519",
    "AgentKeyAlgES256"
  ]
}
AgentIdentityKey

schemas/AgentKeyAlg

{
  "type": "object",
  "description": "One public key bound to an agent identity; the private half never leaves the agent.",
  "required": [
    "id",
    "alg",
    "public_key",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Key id (the `kid` the agent signs with)."
    },
    "alg": {
      "$ref": "#/components/schemas/AgentKeyAlg"
    },
    "public_key": {
      "type": "string",
      "description": "Base64 (standard, padded) public key bytes."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the key was registered."
    },
    "revoked_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When the key was revoked by a rotation; null while active."
    }
  }
}
AgentIdentityKeyRegister

schemas/AgentKeyAlg

{
  "type": "object",
  "required": [
    "alg",
    "public_key"
  ],
  "properties": {
    "alg": {
      "$ref": "#/components/schemas/AgentKeyAlg"
    },
    "public_key": {
      "type": "string",
      "minLength": 32,
      "maxLength": 512,
      "description": "Base64 (standard, padded) public key bytes."
    }
  }
}
AgentKillSwitch

{
  "type": "object",
  "description": "Kill-switch state of an agent identity.",
  "required": [
    "tripped_at",
    "tripped_by",
    "reason"
  ],
  "properties": {
    "tripped_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the switch tripped."
    },
    "tripped_by": {
      "type": "string",
      "description": "Actor label, or the anomaly alert rule that tripped it automatically."
    },
    "reason": {
      "type": "string",
      "description": "Why it tripped."
    },
    "reset_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When it was reset; null while tripped."
    }
  }
}
AgentIdentity

schemas/LifecycleStatusschemas/AgentBandschemas/AgentWriteDefaultschemas/AgentIdentityKeyschemas/AgentKillSwitch

{
  "type": "object",
  "description": "A registered agent principal (SR-1239a agent registry).",
  "required": [
    "id",
    "tenant_id",
    "name",
    "status",
    "band",
    "write_default",
    "keys",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Identity id."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning tenant."
    },
    "name": {
      "type": "string",
      "description": "Operator-facing name."
    },
    "status": {
      "$ref": "#/components/schemas/LifecycleStatus"
    },
    "band": {
      "$ref": "#/components/schemas/AgentBand"
    },
    "write_default": {
      "$ref": "#/components/schemas/AgentWriteDefault"
    },
    "shared_cap_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "Shared spend / action cap the identity draws from (libs/agentgov cap); null = its own cap."
    },
    "keys": {
      "type": "array",
      "description": "Registered keys, newest first (at most one active).",
      "items": {
        "$ref": "#/components/schemas/AgentIdentityKey"
      }
    },
    "kill_switch": {
      "nullable": true,
      "description": "Present while the switch is tripped (or was tripped and reset — see reset_at); null when never tripped.",
      "allOf": [
        {
          "$ref": "#/components/schemas/AgentKillSwitch"
        }
      ]
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "Row creation."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "description": "Last change."
    }
  }
}
AgentIdentityCreate

schemas/AgentBandschemas/AgentWriteDefaultschemas/AgentIdentityKeyRegister

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "description": "Operator-facing name."
    },
    "band": {
      "description": "Initial autonomy band; RECOMMEND when omitted.",
      "allOf": [
        {
          "$ref": "#/components/schemas/AgentBand"
        }
      ]
    },
    "write_default": {
      "description": "Initial write default; DRAFT when omitted.",
      "allOf": [
        {
          "$ref": "#/components/schemas/AgentWriteDefault"
        }
      ]
    },
    "shared_cap_id": {
      "type": "string",
      "format": "uuid",
      "description": "Shared cap to draw from; omitted = its own cap."
    },
    "key": {
      "description": "The agent's first public key; omitted = registered later with rotateAgentIdentityKey (the identity cannot call tools until it has a key).",
      "allOf": [
        {
          "$ref": "#/components/schemas/AgentIdentityKeyRegister"
        }
      ]
    }
  }
}
AgentIdentityBandSet

schemas/AgentBand

{
  "type": "object",
  "required": [
    "band",
    "reason"
  ],
  "properties": {
    "band": {
      "$ref": "#/components/schemas/AgentBand"
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Recorded in the audit envelope."
    }
  }
}
AgentKillSwitchRequest

{
  "type": "object",
  "required": [
    "reason"
  ],
  "properties": {
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Recorded in the audit envelope."
    }
  }
}
AgentIdentityList

schemas/AgentIdentity

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "description": "The page of identities.",
      "items": {
        "$ref": "#/components/schemas/AgentIdentity"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor for the next page; absent on the last page."
    }
  }
}
LlmCallLedgerEntry

{
  "type": "object",
  "description": "One metered language-model call (llm_call_ledger).",
  "required": [
    "id",
    "tenant_id",
    "surface",
    "provider",
    "model",
    "prompt_id",
    "prompt_sha256",
    "input_tokens",
    "output_tokens",
    "cost",
    "currency",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Ledger row id."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Tenant the call was made for."
    },
    "surface": {
      "type": "string",
      "description": "The LLM-backed surface that made the call."
    },
    "provider": {
      "type": "string",
      "description": "Provider adapter key (libs/llm seam)."
    },
    "model": {
      "type": "string",
      "description": "Provider model key the adapter resolved."
    },
    "prompt_id": {
      "type": "string",
      "description": "Pinned prompt id."
    },
    "prompt_sha256": {
      "type": "string",
      "description": "Hex SHA-256 of the pinned prompt text."
    },
    "input_tokens": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Prompt tokens."
    },
    "output_tokens": {
      "type": "integer",
      "format": "int64",
      "minimum": 0,
      "description": "Completion tokens."
    },
    "cost": {
      "type": "string",
      "description": "Decimal metered cost (4 dp)."
    },
    "currency": {
      "type": "string",
      "description": "Cost currency."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the call completed."
    }
  }
}
LlmUsageList

schemas/LlmCallLedgerEntry

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "description": "The page of ledger rows.",
      "items": {
        "$ref": "#/components/schemas/LlmCallLedgerEntry"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor for the next page; absent on the last page."
    }
  }
}
DealSyncDirection

{
  "type": "string",
  "description": "PUSH = sent by this tenant to a partner; RECEIVE = received from a partner.",
  "enum": [
    "PUSH",
    "RECEIVE"
  ],
  "x-enum-varnames": [
    "DealSyncDirectionPUSH",
    "DealSyncDirectionRECEIVE"
  ]
}
DealSyncStatus

{
  "type": "string",
  "description": "Delivery state of a deal sync — PENDING, SENT, ACKNOWLEDGED (partner confirmed), RECEIVED (inbound recorded), FAILED.",
  "enum": [
    "PENDING",
    "SENT",
    "ACKNOWLEDGED",
    "RECEIVED",
    "FAILED"
  ],
  "x-enum-varnames": [
    "DealSyncStatusPENDING",
    "DealSyncStatusSENT",
    "DealSyncStatusACKNOWLEDGED",
    "DealSyncStatusRECEIVED",
    "DealSyncStatusFAILED"
  ]
}
DealSync

schemas/DealSyncDirectionschemas/DealSyncStatus

{
  "type": "object",
  "description": "One deal exchange with a partner (deal_sync row).",
  "required": [
    "id",
    "tenant_id",
    "deal_id",
    "direction",
    "partner_id",
    "status",
    "external_ref",
    "payload_sha256",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Sync row id."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning tenant."
    },
    "deal_id": {
      "type": "string",
      "format": "uuid",
      "description": "The local deal."
    },
    "direction": {
      "$ref": "#/components/schemas/DealSyncDirection"
    },
    "partner_id": {
      "type": "string",
      "format": "uuid",
      "description": "The demand partner (PUSH) or the partner API key's principal (RECEIVE)."
    },
    "status": {
      "$ref": "#/components/schemas/DealSyncStatus"
    },
    "external_ref": {
      "type": "string",
      "description": "The partner's reference for the deal."
    },
    "payload_sha256": {
      "type": "string",
      "description": "Hex SHA-256 of the exchanged payload."
    },
    "error": {
      "type": "string",
      "nullable": true,
      "description": "Partner error when FAILED; null otherwise."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the exchange was recorded."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "description": "Last status change."
    }
  }
}
DealPushRequest

{
  "type": "object",
  "required": [
    "partner_id",
    "reason"
  ],
  "properties": {
    "partner_id": {
      "type": "string",
      "format": "uuid",
      "description": "Demand partner to push the deal to; must have a deal endpoint configured."
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Recorded in the audit envelope."
    }
  }
}
DealInboundRequest

schemas/DealCreate

{
  "type": "object",
  "required": [
    "external_ref",
    "deal"
  ],
  "properties": {
    "external_ref": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "description": "The partner's stable reference for the deal; a second push with the same value updates the deal."
    },
    "deal": {
      "$ref": "#/components/schemas/DealCreate"
    }
  }
}
ConversionIngestEvent

{
  "type": "object",
  "required": [
    "event_name",
    "occurred_at"
  ],
  "properties": {
    "event_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "description": "Conversion event name as configured on the conversion tag."
    },
    "user_key": {
      "type": "string",
      "maxLength": 256,
      "pattern": "^[A-Za-z0-9._:@+-]{1,256}$",
      "description": "Opaque first-party user key (design 33); omitted for unattributable conversions."
    },
    "occurred_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the conversion happened."
    },
    "value": {
      "type": "string",
      "pattern": "^[0-9]+(\\.[0-9]{1,4})?$",
      "description": "Decimal conversion value (4 dp); omitted = no value."
    },
    "currency": {
      "type": "string",
      "minLength": 3,
      "maxLength": 3,
      "description": "Currency of value; required when value is set."
    },
    "order_ref": {
      "type": "string",
      "maxLength": 200,
      "description": "Advertiser-side order / transaction reference used for dedup."
    },
    "attributes": {
      "type": "object",
      "description": "Additional key → value attributes carried on the event.",
      "additionalProperties": {
        "type": "string"
      }
    }
  }
}
ConversionIngestBatch

schemas/ConversionIngestEvent

{
  "type": "object",
  "required": [
    "source",
    "events"
  ],
  "properties": {
    "source": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "description": "Where the batch comes from (e.g. crm, warehouse); recorded on the batch."
    },
    "events": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1000,
      "description": "The conversion events.",
      "items": {
        "$ref": "#/components/schemas/ConversionIngestEvent"
      }
    }
  }
}
ConversionIngestError

{
  "type": "object",
  "required": [
    "index",
    "message"
  ],
  "properties": {
    "index": {
      "type": "integer",
      "minimum": 0,
      "description": "Position of the rejected event in the batch."
    },
    "message": {
      "type": "string",
      "description": "Why it was rejected."
    }
  }
}
ConversionIngestResult

schemas/ConversionIngestError

{
  "type": "object",
  "required": [
    "batch_id",
    "accepted",
    "rejected",
    "sha256"
  ],
  "properties": {
    "batch_id": {
      "type": "string",
      "format": "uuid",
      "description": "The conversion_ingest_batch row."
    },
    "accepted": {
      "type": "integer",
      "minimum": 0,
      "description": "Events published."
    },
    "rejected": {
      "type": "integer",
      "minimum": 0,
      "description": "Events rejected."
    },
    "sha256": {
      "type": "string",
      "description": "Hex SHA-256 of the batch payload (dedup key)."
    },
    "errors": {
      "type": "array",
      "description": "One row per rejected event.",
      "items": {
        "$ref": "#/components/schemas/ConversionIngestError"
      }
    }
  }
}
PrivacyRequestKind

{
  "type": "string",
  "description": "Data-subject request kind — ACCESS (export what is held), ERASURE (delete), OPT_OUT (stop processing for targeting).",
  "enum": [
    "ACCESS",
    "ERASURE",
    "OPT_OUT"
  ],
  "x-enum-varnames": [
    "PrivacyRequestKindACCESS",
    "PrivacyRequestKindERASURE",
    "PrivacyRequestKindOPTOUT"
  ]
}
PrivacyRequestStatus

{
  "type": "string",
  "description": "Processing state — RECEIVED, IN_PROGRESS, COMPLETED, REJECTED (with the reason in evidence).",
  "enum": [
    "RECEIVED",
    "IN_PROGRESS",
    "COMPLETED",
    "REJECTED"
  ],
  "x-enum-varnames": [
    "PrivacyRequestStatusRECEIVED",
    "PrivacyRequestStatusINPROGRESS",
    "PrivacyRequestStatusCOMPLETED",
    "PrivacyRequestStatusREJECTED"
  ]
}
PrivacyRequest

schemas/PrivacyRequestKindschemas/PrivacyRequestStatus

{
  "type": "object",
  "description": "One data-subject request (privacy_request row).",
  "required": [
    "id",
    "tenant_id",
    "kind",
    "subject_key_hash",
    "status",
    "requested_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Request id."
    },
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "Owning tenant."
    },
    "kind": {
      "$ref": "#/components/schemas/PrivacyRequestKind"
    },
    "subject_key_hash": {
      "type": "string",
      "description": "Hex SHA-256 of the subject's user key; the key itself is never stored."
    },
    "status": {
      "$ref": "#/components/schemas/PrivacyRequestStatus"
    },
    "requested_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the request was filed."
    },
    "completed_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true,
      "description": "When processing finished; null while open."
    },
    "evidence": {
      "type": "object",
      "description": "What was done, per store (profiles, memberships, events) — step → outcome.",
      "additionalProperties": true
    }
  }
}
PrivacyRequestCreate

schemas/PrivacyRequestKind

{
  "type": "object",
  "required": [
    "kind",
    "subject_key",
    "reason"
  ],
  "properties": {
    "kind": {
      "$ref": "#/components/schemas/PrivacyRequestKind"
    },
    "subject_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "^[A-Za-z0-9._:@+-]{1,256}$",
      "description": "Opaque first-party user key of the data subject; hashed at rest."
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Recorded in the audit envelope."
    }
  }
}
PrivacyRequestList

schemas/PrivacyRequest

{
  "type": "object",
  "required": [
    "items"
  ],
  "properties": {
    "items": {
      "type": "array",
      "description": "The page of requests.",
      "items": {
        "$ref": "#/components/schemas/PrivacyRequest"
      }
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor for the next page; absent on the last page."
    }
  }
}
ServingDiagnosis

schemas/DiagnoseDeliveryResultschemas/EligibilityReport

{
  "type": "object",
  "description": "Structured serving diagnosis for a line item (SR-1234); `diagnosis` and `summary` are what the MCP diagnose_delivery tool returns.",
  "required": [
    "line_item_ref",
    "serving",
    "diagnosis",
    "summary",
    "as_of"
  ],
  "properties": {
    "line_item_ref": {
      "type": "string",
      "description": "The line item diagnosed."
    },
    "line_item_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true,
      "description": "Resolved id; null when the ref matched nothing (diagnosis then says so)."
    },
    "serving": {
      "type": "boolean",
      "description": "Whether the line item is currently eligible to serve."
    },
    "diagnosis": {
      "$ref": "#/components/schemas/DiagnoseDeliveryResult"
    },
    "eligibility": {
      "nullable": true,
      "description": "The deterministic eligibility report (getLineItemEligibility); null when the ref matched nothing.",
      "allOf": [
        {
          "$ref": "#/components/schemas/EligibilityReport"
        }
      ]
    },
    "summary": {
      "type": "string",
      "description": "The diagnosis rendered as text — byte-for-byte the MCP tool's rendering (console \"Copy diagnosis\")."
    },
    "as_of": {
      "type": "string",
      "format": "date-time",
      "description": "Injected clock instant of the diagnosis."
    }
  }
}
SampleDataLoadResult

{
  "type": "object",
  "required": [
    "tenant_id",
    "loaded_at",
    "counts"
  ],
  "properties": {
    "tenant_id": {
      "type": "string",
      "format": "uuid",
      "description": "The sandbox tenant."
    },
    "loaded_at": {
      "type": "string",
      "format": "date-time",
      "description": "When the load completed."
    },
    "counts": {
      "type": "object",
      "description": "Entity kind → rows created (publisher, placement, advertiser, campaign_order, line_item, creative, audience, fee_schedule).",
      "additionalProperties": {
        "type": "integer"
      }
    }
  }
}