{
    "openapi": "3.0.0",
    "info": {
        "title": "JuJu API",
        "description": "Public and partner-facing endpoints for the JuJu jobs platform. Covers job search, click attribution, publisher API integration, and the consumer/admin/sponsor/publisher portals.",
        "contact": {
            "name": "JuJu Engineering",
            "email": "engineering@juju.com"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://api.juju.com",
            "description": "Publisher B2B API (external partners, api_auth Bearer keys)"
        },
        {
            "url": "https://webapi.juju.com",
            "description": "Consumer Web API (SPA backend, hmac:webapi)"
        },
        {
            "url": "https://adminapi.juju.com",
            "description": "Admin API (hmac:admin + session)"
        },
        {
            "url": "https://sponsorapi.juju.com",
            "description": "Sponsor Portal API (hmac:sponsor + session)"
        },
        {
            "url": "https://publisherapi.juju.com",
            "description": "Publisher Portal API (hmac:publisher + session)"
        },
        {
            "url": "http://localhost:8080",
            "description": "Local development (no hostname lock)"
        }
    ],
    "paths": {
        "/admin/v1/admin-users": {
            "get": {
                "tags": [
                    "Admin User"
                ],
                "summary": "Admin User - List",
                "operationId": "058ac7fc1836de4220c52d11f0b9824f",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Substring against username or email.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "role",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "username",
                                "first_name",
                                "last_name",
                                "email",
                                "role",
                                "date_created",
                                "date_last_login",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated admin-user list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/AdminUser"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Admin User"
                ],
                "summary": "Admin User - Create",
                "description": "Body: username*, password*, email*, first_name, last_name, phone (optional; E.164-normalized), role (default 'admin'). Password minimum 12 chars.",
                "operationId": "cd0a8e85ac03b7081c568d18da71625b",
                "responses": {
                    "201": {
                        "description": "Created admin user.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AdminUser"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Username or email already taken.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/admin-users/{id}": {
            "get": {
                "tags": [
                    "Admin User"
                ],
                "summary": "Admin User - Detail",
                "operationId": "6ea6771df6f0edcbf9c4ac594088aa1c",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Admin-user detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AdminUser"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Admin User"
                ],
                "summary": "Admin User - Deactivate",
                "description": "Sets active=false. Row survives for audit continuity; user's next login attempt returns 401 (partial-unique-on-username-active lets a fresh admin re-register the username if needed).",
                "operationId": "b04621206492319c53da37757ac32988",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated admin user.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AdminUser"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Admin User"
                ],
                "summary": "Admin User - Update",
                "description": "Partial update (non-secret fields). Mutable: first_name, last_name, role, phone (E.164 normalized), email (resolves to juju.email artifact). Username is immutable (audit-log continuity). Password uses /reset-password.",
                "operationId": "84cafd5831e8d859e1bd7f2068e0223e",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated admin user.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AdminUser"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/admin-users/{id}/reset-password": {
            "post": {
                "tags": [
                    "Admin User"
                ],
                "summary": "Admin User - Reset Password",
                "description": "Admin sets the password out-of-band and communicates it to the user directly (until email-based reset flows land). Body: password* (min 12 chars). Returns 200 with {reset: true} — envelope-consistent rather than the RFC-canonical 204 No Content.",
                "operationId": "60341963e8c5cd5ab957ef71f181a457",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Password reset succeeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "reset": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Password too short.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/auth/login": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Auth - Login",
                "description": "Body: {username, password}. Success mints an admin-audience JWT (8h TTL default), sets it as an httpOnly + SameSite=Lax cookie, stamps date_last_login on the admin_user row, and returns the admin's public profile. Failures return 401 with a generic \"Invalid credentials.\" message — same response for unknown username and wrong password to avoid user enumeration.",
                "operationId": "7ee1413dc042ab5c693f52fa5f4bf3ea",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "username",
                                    "password"
                                ],
                                "properties": {
                                    "username": {
                                        "type": "string",
                                        "example": "brooke",
                                        "maxLength": 64
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "correct-horse-battery-staple"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Login succeeded. Session cookie set on response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "username": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "role": {
                                                            "type": "string",
                                                            "example": "admin"
                                                        },
                                                        "date_last_login": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Wrong credentials. Same body for unknown username and wrong password.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate-limited (admin `login` bucket: 10/min/IP).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/auth/logout": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Auth - Logout",
                "description": "Sets the session cookie to empty with immediate expiry. Stateless JWTs — no server-side session row to destroy; if the client presents the old cookie value on a subsequent request the SessionAuth filter rejects it once the JWT expiry passes. Idempotent — always returns 200.",
                "operationId": "0563d69f53a314b132442bb24375e65f",
                "responses": {
                    "200": {
                        "description": "Cookie cleared (idempotent).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "logged_out": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/adjustments": {
            "get": {
                "tags": [
                    "Adjustment"
                ],
                "summary": "Adjustment - List",
                "operationId": "e978b3b5950e73cc0d177679ef8d0ae1",
                "parameters": [
                    {
                        "name": "account_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "sponsor",
                                "publisher"
                            ]
                        }
                    },
                    {
                        "name": "account_ref",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "applied",
                                "void"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated adjustment list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Adjustment"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Adjustment"
                ],
                "summary": "Adjustment - Issue",
                "description": "Issue a pending credit/debit. Body: account_type* (sponsor|publisher), account_ref* (job_partner_id or publisher_id), direction* (credit|debit), amount* (>0), reason*. Applied to the next invoice/payout for that account.",
                "operationId": "281438f12b350d14e7c8c36566d78022",
                "responses": {
                    "201": {
                        "description": "Issued adjustment.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Adjustment"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/invoices": {
            "get": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - List",
                "operationId": "5b2384e870a9cb2c0b12e4dccdc02578",
                "parameters": [
                    {
                        "name": "job_partner_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "draft",
                                "open",
                                "paid",
                                "partially_paid",
                                "void",
                                "uncollectible"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "date_created",
                                "issued_at",
                                "due_at",
                                "total",
                                "status"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated invoice list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Invoice"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/invoices/{id}": {
            "get": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - Detail",
                "operationId": "a901c3c6ae52e73c9dbb4a32686b9a08",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Invoice + line items + payments applied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Invoice"
                                                        },
                                                        {
                                                            "properties": {
                                                                "line_items": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "object"
                                                                    }
                                                                },
                                                                "payments": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Payment"
                                                                    }
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/invoices/{id}/issue": {
            "post": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - Issue",
                "description": "Draft → open: stamps issued_at/due_at and posts the sponsor ledger debit.",
                "operationId": "d588b5aa740801c89a7365127a96a71b",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Issued invoice.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Invoice"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not a draft.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/invoices/{id}/void": {
            "post": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - Void",
                "description": "Voids an unpaid invoice. A draft voids cleanly; an issued (open) invoice also posts a compensating sponsor ledger credit to reverse its debit. Invoices with any payment applied cannot be voided (refund first).",
                "operationId": "a5667481fccdedb0abf5aff98fe3d1ea",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Voided invoice.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Invoice"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not voidable (paid / already void).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/sponsors/{partner}/balance": {
            "get": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - Sponsor Balance",
                "description": "Sponsor AR balance from the ledger: Σ invoiced − Σ paid − Σ credits. Positive = owes us; negative = on-account credit.",
                "operationId": "656b20cbcb4892e1e6076a8d15f93ccd",
                "parameters": [
                    {
                        "name": "partner",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Balance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "job_partner_id": {
                                                            "type": "integer"
                                                        },
                                                        "balance": {
                                                            "type": "string",
                                                            "example": "4211.5500"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payments": {
            "get": {
                "tags": [
                    "Payment"
                ],
                "summary": "Payment - List",
                "operationId": "1d19c7b8e7e454a2fefb2e9dd635fce8",
                "parameters": [
                    {
                        "name": "job_partner_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated payment list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Payment"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Payment"
                ],
                "summary": "Payment - Record",
                "description": "Record a received sponsor payment (check/ACH/wire/manual) and apply it across invoices. Body: job_partner_id*, amount*, method*, applications (array of {invoice_id, amount}; sum must be ≤ amount; any remainder becomes on-account credit), received_at, notes.",
                "operationId": "0b8921ca57345f8a6b0e28357af52cad",
                "responses": {
                    "201": {
                        "description": "Recorded payment.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Payment"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payouts": {
            "get": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - List",
                "operationId": "033df7bba98a853d0b63d18223b2633c",
                "parameters": [
                    {
                        "name": "publisher_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "draft",
                                "pending",
                                "in_transit",
                                "paid",
                                "failed",
                                "returned",
                                "on_hold"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated payout list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Payout"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payouts/{id}": {
            "get": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - Detail",
                "operationId": "1c01719ab2d5c8630d3fa3c83a3c6d13",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Payout + line items.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Payout"
                                                        },
                                                        {
                                                            "properties": {
                                                                "line_items": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "object"
                                                                    }
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payouts/{id}/issue": {
            "post": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - Issue",
                "description": "Draft → pending: queues the transfer and posts the publisher ledger credit (earnings recognized). The actual bank transfer runs through the gateway once wired.",
                "operationId": "ff28e27d1ad2aeb9062706bd11fe5a53",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Issued payout.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Payout"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not a draft.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payouts/{id}/hold": {
            "post": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - Hold",
                "description": "Pause a draft/pending payout so the transfer worker skips it. Does not change the ledger (we still owe it) — just delays sending.",
                "operationId": "ad27e896f637fedf8b697b64d78c6bd7",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Held payout.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Payout"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not holdable.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payouts/{id}/release": {
            "post": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - Release",
                "description": "Un-hold a payout. Returns to pending if it was already issued (a ledger credit exists), else back to draft for re-issue.",
                "operationId": "afe5e54a57803efff9c4f63ea848600c",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Released payout.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Payout"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not on hold.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/publishers/{pub}/balance": {
            "get": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - Publisher Balance",
                "description": "Publisher AP balance from the ledger (committed-but-unsettled payouts + adjustments). Positive = we owe them.",
                "operationId": "f57626d35b949df8c623069ec0a94813",
                "parameters": [
                    {
                        "name": "pub",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Balance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "publisher_id": {
                                                            "type": "integer"
                                                        },
                                                        "balance": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/sponsor-profiles": {
            "get": {
                "tags": [
                    "Billing Profile"
                ],
                "summary": "Billing Profile - List Sponsors",
                "operationId": "ffdb5e0ffe7833af8efe1c1c8f1160bc",
                "responses": {
                    "200": {
                        "description": "Sponsor billing profiles.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/sponsor-profiles/{partner}": {
            "get": {
                "tags": [
                    "Billing Profile"
                ],
                "summary": "Billing Profile - Sponsor Detail",
                "operationId": "8e92dbbded8dc556fe5df5638c3300a2",
                "parameters": [
                    {
                        "name": "partner",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "tags": [
                    "Billing Profile"
                ],
                "summary": "Billing Profile - Upsert Sponsor",
                "description": "Create or update. Body: billing_mode* (invoice|auto_charge); invoice mode requires payment_terms_days, auto_charge requires billing_anchor_day (1-28); plus billing_email, currency, tax_exempt, tax_rate, status.",
                "operationId": "3c0cb5ba2752ee060d8e2b7d6af12190",
                "parameters": [
                    {
                        "name": "partner",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Upserted profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/sponsor-profiles/{partner}/payment-methods": {
            "get": {
                "tags": [
                    "Billing Profile"
                ],
                "summary": "Billing Profile - Sponsor Payment Methods",
                "operationId": "6e74596ee74bd9666d3967ee64ef8c4f",
                "parameters": [
                    {
                        "name": "partner",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Tokenized methods (display metadata only — no PAN).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payout-profiles": {
            "get": {
                "tags": [
                    "Billing Profile"
                ],
                "summary": "Billing Profile - List Payout",
                "operationId": "d3c7c810f6d495a0afba5956e46b7814",
                "responses": {
                    "200": {
                        "description": "Payout profiles.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/billing/payout-profiles/{publisher}": {
            "get": {
                "tags": [
                    "Billing Profile"
                ],
                "summary": "Billing Profile - Payout Detail",
                "operationId": "d069ea53f9b64afc139f2146cf157c27",
                "parameters": [
                    {
                        "name": "publisher",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "tags": [
                    "Billing Profile"
                ],
                "summary": "Billing Profile - Upsert Payout",
                "description": "Create or update. Body: payout_method (ach|check|wire), minimum_payout, payout_schedule (monthly|weekly), on_hold, currency, status. Bank tokens are set via hosted-field tokenization, not here.",
                "operationId": "df9b4e259840f2fc7b4441456034f786",
                "parameters": [
                    {
                        "name": "publisher",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Upserted profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/campaigns": {
            "get": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - List",
                "operationId": "6e689f52604f2f180a0acc1aa53ca779",
                "parameters": [
                    {
                        "name": "provider_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "paused",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "budget_type",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "daily",
                                "monthly",
                                "flight",
                                "unlimited"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "date_updated",
                                "active",
                                "paused",
                                "budget",
                                "default_cpc",
                                "budget_type",
                                "start_date",
                                "end_date"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated campaign list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Campaign"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Create",
                "description": "Required: job_provider_id, name, budget_type. Conditional: budget (required unless budget_type=unlimited); start_date + end_date (required when budget_type=flight, forbidden otherwise). API-level validation runs first so callers get clean error messages instead of raw DB constraint violations.",
                "operationId": "2a6b97bffc8cb4db68a954b8c8d2def4",
                "responses": {
                    "201": {
                        "description": "Created campaign (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Campaign"
                                                        },
                                                        {
                                                            "properties": {
                                                                "segments": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Segment"
                                                                    }
                                                                },
                                                                "spend_to_date": {
                                                                    "description": "Money as string — cumulative spend from click_sponsor_daily_rollup, ~5min stale.",
                                                                    "type": "string",
                                                                    "example": "0.00"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/campaigns/{id}": {
            "get": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Detail",
                "operationId": "db54c0821ed5dc49659f1df94a1b6f5d",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Campaign detail — list-row fields + segments + spend_to_date.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Campaign"
                                                        },
                                                        {
                                                            "properties": {
                                                                "segments": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Segment"
                                                                    }
                                                                },
                                                                "spend_to_date": {
                                                                    "type": "string",
                                                                    "example": "4211.55"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Deactivate",
                "operationId": "90602b67fb0f37ee8bff182cf0e18f57",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated campaign (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Campaign"
                                                        },
                                                        {
                                                            "properties": {
                                                                "segments": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Segment"
                                                                    }
                                                                },
                                                                "spend_to_date": {
                                                                    "type": "string",
                                                                    "example": "4211.55"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Update",
                "description": "Partial update — config fields only. Mutable: job_provider_id, name, test_mode, promotional, organic, budget_type, pricing_model, budget, default_cpc, start_date, end_date. job_provider_id re-parents the campaign (target must exist); pricing_model is cpc|cpa. Use action endpoints for pause/resume/delete. Same conditional validation as create (flight requires dates; unlimited forbids budget).",
                "operationId": "282579c0e519451a394a1536bb379597",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated campaign (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Campaign"
                                                        },
                                                        {
                                                            "properties": {
                                                                "segments": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Segment"
                                                                    }
                                                                },
                                                                "spend_to_date": {
                                                                    "type": "string",
                                                                    "example": "4211.55"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/campaigns/{id}/pause": {
            "post": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Pause",
                "operationId": "eec90e0221216792469c0bbbeb3608c2",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paused campaign (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Campaign"
                                                        },
                                                        {
                                                            "properties": {
                                                                "segments": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Segment"
                                                                    }
                                                                },
                                                                "spend_to_date": {
                                                                    "type": "string",
                                                                    "example": "4211.55"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/campaigns/{id}/resume": {
            "post": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Resume",
                "operationId": "403c2fb394d04446c8434eb52b200104",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resumed campaign (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Campaign"
                                                        },
                                                        {
                                                            "properties": {
                                                                "segments": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Segment"
                                                                    }
                                                                },
                                                                "spend_to_date": {
                                                                    "type": "string",
                                                                    "example": "4211.55"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/campaigns/{id}/segments": {
            "get": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - List Segments",
                "description": "Paginated. Realistic sets are small (a handful per campaign), but the meta block is included for shape consistency with every other list endpoint on this surface.",
                "operationId": "4551d9ad0da47d2306919281b3e9126c",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "bid_low",
                                "bid_high",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated segment list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Segment"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Create Segment",
                "description": "Body: name*, criteria* (JSONB), bid_low*, bid_high*, prefer_high_bid. CPA campaigns also accept conversion_rate_assumed, effective_cpc_override, observation_tuning_enabled; conversion_rate_working is seeded from the assumed rate. On a CPA campaign, bid_low/bid_high are denominated in CPA dollars.",
                "operationId": "a66b0c7e2a6465c5b49fa44c36ddab66",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created segment.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Segment"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/consent-documents": {
            "get": {
                "tags": [
                    "Consent"
                ],
                "summary": "Consent - List",
                "description": "Paginated list of consent documents (newest first). Optional `consent_type` filter. body_html is omitted here (it can be large) — fetch a single document for the full body.",
                "operationId": "5184951937c5fcd4aee6f8856015a205",
                "parameters": [
                    {
                        "name": "consent_type",
                        "in": "query",
                        "description": "Filter to one type, e.g. terms_of_service.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "date_created",
                                "consent_type",
                                "version",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated list (body_html omitted).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ConsentDocument"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Consent"
                ],
                "summary": "Consent - Publish Version",
                "description": "Publishes a NEW consent-document version (the table is immutable; this is how you \"edit\"). When active=true (default), the prior active document of the same consent_type + offer_id is deactivated so exactly one stays live. body_html holds plain text or HTML. partners is an optional JSON snapshot of disclosed partners (TCPA).",
                "operationId": "95f269cf291c559af4e38fd8acc2d839",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "consent_type",
                                    "version",
                                    "body_html"
                                ],
                                "properties": {
                                    "consent_type": {
                                        "type": "string",
                                        "example": "terms_of_service",
                                        "maxLength": 32
                                    },
                                    "version": {
                                        "type": "string",
                                        "example": "2026-08-18",
                                        "maxLength": 32
                                    },
                                    "body_html": {
                                        "type": "string"
                                    },
                                    "offer_id": {
                                        "description": "Only for offer-specific consents; null for site-level.",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "sms_disclosure": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "partners": {
                                        "type": "array",
                                        "items": {
                                            "type": "object"
                                        },
                                        "nullable": true
                                    },
                                    "active": {
                                        "type": "boolean",
                                        "default": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "New version published.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ConsentDocument"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/consent-documents/{id}": {
            "get": {
                "tags": [
                    "Consent"
                ],
                "summary": "Consent - Display",
                "description": "Full document including body_html, partners snapshot, and sms_disclosure.",
                "operationId": "76832ef5f0afd1016f4408c92b9c76bd",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Full consent document.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ConsentDocument"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/consent-documents/{id}/deactivate": {
            "post": {
                "tags": [
                    "Consent"
                ],
                "summary": "Consent - Deactivate",
                "description": "Sets active=false on a consent document (e.g. retiring a type without publishing a replacement). Idempotent.",
                "operationId": "afa2c345fb989c29d1ddb40150a198c0",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated document.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ConsentDocument"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/dashboard": {
            "get": {
                "tags": [
                    "Dashboard"
                ],
                "summary": "Dashboard - Get",
                "description": "Aggregate for the admin landing screen. Single call — one HTTP request per dashboard render. Cached 60s. Blocks degrade individually on source failure (Solr down → jobs.indexed_total = 0; PG hiccup on one query → that block's counts drop to 0). Endpoint never 500s.",
                "operationId": "43d1f2bb6e777c83f0b89bfeeba0f112",
                "responses": {
                    "200": {
                        "description": "Dashboard payload.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "jobs": {
                                                            "properties": {
                                                                "indexed_total": {
                                                                    "type": "integer"
                                                                },
                                                                "providers_active": {
                                                                    "type": "integer"
                                                                },
                                                                "providers_paused": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "campaigns": {
                                                            "properties": {
                                                                "live": {
                                                                    "type": "integer"
                                                                },
                                                                "paused": {
                                                                    "type": "integer"
                                                                },
                                                                "budget_cache": {
                                                                    "type": "object"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "clicks_today": {
                                                            "properties": {
                                                                "total": {
                                                                    "type": "integer"
                                                                },
                                                                "billable": {
                                                                    "type": "integer"
                                                                },
                                                                "bot": {
                                                                    "type": "integer"
                                                                },
                                                                "duplicate": {
                                                                    "type": "integer"
                                                                },
                                                                "spend": {
                                                                    "type": "string",
                                                                    "example": "4211.55"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "leads_today": {
                                                            "properties": {
                                                                "submitted": {
                                                                    "type": "integer"
                                                                },
                                                                "delivered": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "feeds": {
                                                            "properties": {
                                                                "last_run_completed": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true
                                                                },
                                                                "runs_active": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "notifications": {
                                                            "description": "Shared inbox summary for the login badge (~60s cached; the /notifications endpoint is real-time).",
                                                            "properties": {
                                                                "open_count": {
                                                                    "type": "integer"
                                                                },
                                                                "actionable_count": {
                                                                    "description": "open + acknowledged",
                                                                    "type": "integer"
                                                                },
                                                                "critical_count": {
                                                                    "type": "integer"
                                                                },
                                                                "recent": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/Notification"
                                                                    }
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    },
                                                    "type": "object"
                                                },
                                                "meta": {
                                                    "properties": {
                                                        "generated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/feed-runs": {
            "get": {
                "tags": [
                    "Feed Run"
                ],
                "summary": "Feed Run - List",
                "description": "Paginated. Filters: provider_id, since (ISO date). Ordered by time_started DESC.",
                "operationId": "08e2d2824a5c476a1d283cbffd6d7600",
                "parameters": [
                    {
                        "name": "provider_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "since",
                        "in": "query",
                        "description": "ISO 8601 timestamp lower bound on time_started.",
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "run_id",
                                "time_started",
                                "time_processing_finished",
                                "workers_active",
                                "total_jobs_in_file"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated run list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/RunInfo"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/feed-runs/{run_id}": {
            "get": {
                "tags": [
                    "Feed Run"
                ],
                "summary": "Feed Run - Detail",
                "operationId": "c53f905c5407d76f9b4b2ddc65f77c3e",
                "parameters": [
                    {
                        "name": "run_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Run detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/RunInfo"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/health": {
            "get": {
                "tags": [
                    "Health"
                ],
                "summary": "Health - Admin Liveness",
                "description": "Unauthenticated. Returns ok=true if the admin module is loaded and the response pipeline is healthy. Wire into LB health checks. Does NOT exercise downstream dependencies (DB, Solr, Memcached) — keep those out so a failing dependency doesn't cycle the LB target.",
                "operationId": "5186a3cfe237fb5e6f51a135ec9135de",
                "responses": {
                    "200": {
                        "description": "Module is up.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "required": [
                                                        "ok"
                                                    ],
                                                    "properties": {
                                                        "ok": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/lookups": {
            "get": {
                "tags": [
                    "Lookup"
                ],
                "summary": "Lookup - Aggregate",
                "description": "Admin form-population lookups (single aggregate). One call returns campaign_budget_types, job_partners, work_types, and job_groups. Cached ~5min in Memcached. Use for admin SPA form dropdowns.",
                "operationId": "ccc1a5900eb7dcb0e9576e022724d257",
                "responses": {
                    "200": {
                        "description": "Lookups payload — full aggregate.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Lookups"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/me": {
            "get": {
                "tags": [
                    "Me"
                ],
                "summary": "Me - Get Profile",
                "description": "Returns the profile fields for the admin identified by the session cookie. Same shape as the login response. The admin_user_id comes from the session, NOT the URL — an admin can never read another admin's profile via this endpoint.",
                "operationId": "efe617a0ea26d2f8127787fab7bac6c5",
                "responses": {
                    "200": {
                        "description": "Current admin profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "username": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "role": {
                                                            "type": "string",
                                                            "example": "admin"
                                                        },
                                                        "date_created": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "date_last_login": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No valid session cookie, OR session's admin_user_id no longer maps to an active admin.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/notifications": {
            "get": {
                "tags": [
                    "Notification"
                ],
                "summary": "Notification - List",
                "description": "Filters: status, severity, type. Defaults to actionable (open + acknowledged) newest-activity-first when no status is given.",
                "operationId": "72aad34ebe702cb8ad9e1bfe19efe8d3",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "open",
                                "acknowledged",
                                "resolved",
                                "dismissed",
                                "actionable"
                            ]
                        }
                    },
                    {
                        "name": "severity",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "info",
                                "warning",
                                "critical"
                            ]
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated notifications.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Notification"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/notifications/{id}": {
            "get": {
                "tags": [
                    "Notification"
                ],
                "summary": "Notification - Detail",
                "operationId": "42f6257fdc90a061d0ed42d4f01d76ea",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Notification.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Notification"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/notifications/{id}/acknowledge": {
            "post": {
                "tags": [
                    "Notification"
                ],
                "summary": "Notification - Acknowledge",
                "description": "Claim an open notification (\"I'm on it\"). Stamps acknowledged_by + time.",
                "operationId": "3c7790c0f0c897ef901bd5a7a1c0066a",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Acknowledged.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Notification"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Not open.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/notifications/{id}/resolve": {
            "post": {
                "tags": [
                    "Notification"
                ],
                "summary": "Notification - Resolve",
                "description": "Mark done. Body: note (optional resolution note — what was done). Allowed from open or acknowledged.",
                "operationId": "184a691d816b9da99898e0046501eb13",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resolved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Notification"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already resolved/dismissed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/notifications/{id}/dismiss": {
            "post": {
                "tags": [
                    "Notification"
                ],
                "summary": "Notification - Dismiss",
                "description": "Mark not-actionable / noise. Allowed from open or acknowledged.",
                "operationId": "fc68873355d53e9de36ad095d52bbad5",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Dismissed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Notification"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Already resolved/dismissed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{list_id}/offers": {
            "get": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - List Members",
                "description": "Paginated members of the list, each joined to a summary of the parent offer. By default excludes rows where offer.active = false (matches the matcher's view); pass `include_inactive=true` to see all junction rows including those with deactivated parent offers.",
                "operationId": "fe907e92a170accd1d2aaa929d53eedb",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "include_inactive",
                        "in": "query",
                        "description": "Include rows where offer.active = false. Default false.",
                        "schema": {
                            "type": "boolean",
                            "default": false
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated members.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/OfferListMember"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "List not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Add Offer",
                "description": "Body: offer_id* (required), weight (1..100, default 10), position (nullable). If the offer's active flag is false, this call ALSO flips it back to true — \"re-adding to a list reinstates the offer\" per the ops workflow. Duplicate membership returns 409.",
                "operationId": "094157a4bca506edc5866c4dd1a51936",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created member row.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferListMember"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "List or offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Offer already in this list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{list_id}/offers/{offer_id}": {
            "delete": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Remove Offer",
                "description": "Hard-deletes the junction row. The parent offer is untouched; other list memberships remain. Idempotent — deleting a non-existent row returns 200 with removed=false.",
                "operationId": "d2e19b42d3e93690efd42b95d6a42186",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "removed": {
                                                            "type": "boolean"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Update Member",
                "description": "Mutable: weight, position, active (junction-row active, not the parent offer's).",
                "operationId": "3ee94ba1a9419810071c76a7ee5962fc",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferListMember"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Member row not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{list_id}/publishers": {
            "get": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - List Publishers",
                "description": "Publisher context assignments, ordered by priority DESC.",
                "operationId": "d2224ac55498dc18b85bb046680b5e5a",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Assignments.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "offer_list_id": {
                                                                "type": "integer"
                                                            },
                                                            "publisher_id": {
                                                                "type": "integer"
                                                            },
                                                            "publisher_name": {
                                                                "type": "string"
                                                            },
                                                            "priority": {
                                                                "type": "integer"
                                                            },
                                                            "date_created": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "List not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Add Publisher",
                "description": "Body: publisher_id*, priority (default 0). Duplicate publisher on the same list returns 409 — use PATCH to update priority.",
                "operationId": "1f4f142baf4e9ad61fc34edb86499429",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "List or publisher not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Publisher already assigned to this list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{list_id}/publishers/{publisher_id}": {
            "delete": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Remove Publisher",
                "operationId": "e5f044b15fd3e99ff813b54c27f28d52",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "publisher_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Update Publisher Priority",
                "description": "Body: priority* (integer). Updates the ordering hint used when multiple lists match one publisher.",
                "operationId": "69600bcc5a7c90e461c7a0de732a79d7",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "publisher_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Row not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{list_id}/sponsors": {
            "get": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - List Sponsors",
                "description": "Sponsor context assignments — both allow and block.",
                "operationId": "4cce992bebcbcf7c402bd8f90926325e",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Assignments.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "offer_list_id": {
                                                                "type": "integer"
                                                            },
                                                            "sponsor_id": {
                                                                "type": "integer"
                                                            },
                                                            "sponsor_name": {
                                                                "type": "string"
                                                            },
                                                            "is_blocklist": {
                                                                "type": "boolean"
                                                            },
                                                            "date_created": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "List not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Add Sponsor",
                "description": "Body: sponsor_id* (aka job_partner_id), is_blocklist (default false). A single sponsor can appear at most once per list — POSTing twice for the same sponsor returns 409. Use PATCH to flip is_blocklist on an existing row.",
                "operationId": "502f766b372ceb6ea8b538b4d32987f3",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "List or sponsor not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Sponsor already assigned to this list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{list_id}/sponsors/{sponsor_id}": {
            "delete": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Remove Sponsor",
                "operationId": "7987190604054003b74e78032dcbf86c",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sponsor_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Toggle Sponsor is_blocklist",
                "description": "Body: is_blocklist* (bool). Flips allow ↔ block for the existing row.",
                "operationId": "4b68017462976fa8213887b0ceeba2cf",
                "parameters": [
                    {
                        "name": "list_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sponsor_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Row not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists": {
            "get": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - List",
                "description": "Paginated. Filters: q (substring on name), active.",
                "operationId": "204a7567be089dfef57f0f9b8e556177",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated list of offer lists. Rows do NOT include counts — see detail for that.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/OfferList"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Create",
                "description": "Body: name*, description, active (defaults true). Creates the empty bundle — add members via nested endpoints, or use POST /duplicate on an existing list to clone it.",
                "operationId": "fde1933d23299c8cd7efc4c6b428ec42",
                "responses": {
                    "201": {
                        "description": "Created list (with zeroed counts).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferList"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{id}": {
            "get": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Detail",
                "description": "Includes membership counts (offers, sponsors_allow, sponsors_block, publishers). `offers` count uses active-only semantics — matches what the matcher considers.",
                "operationId": "9a4ac1b6c8fbf512092ca5083cc05454",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List detail with counts.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferList"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Deactivate",
                "operationId": "7b9bdddbc3b0ed5f3c6cf39cf164e374",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferList"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Update",
                "description": "Mutable: name, description, active. Use DELETE for soft-deactivation.",
                "operationId": "6a89ec04d9e663f87e087c177a1312ac",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferList"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-lists/{id}/duplicate": {
            "post": {
                "tags": [
                    "Offer List"
                ],
                "summary": "Offer List - Duplicate",
                "description": "Clones the list row + every offer / sponsor / publisher junction row into a new list_id, in one transaction. Body: {name?} — defaults to `\"{original name} (copy)\"` when not supplied. New list starts `active=true`. All junction rows carry over their weights / positions / is_blocklist / priority values unchanged.",
                "operationId": "14c62d41c4e8bd7683b1f51e11f788d5",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Duplicated list detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferList"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Source list not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Duplicate transaction failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-partners": {
            "get": {
                "tags": [
                    "Offer Partner"
                ],
                "summary": "Offer Partner - List",
                "description": "Paginated. Filters: q (substring on name), active.",
                "operationId": "b8c97f7fd38f7cf22953972849d7befc",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated offer-partner list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/OfferPartner"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer Partner"
                ],
                "summary": "Offer Partner - Create",
                "description": "Body: name*, logo_url, contact_name, contact_email, contact_phone, offer_defaults (JSONB — used to pre-fill new offers).",
                "operationId": "2604f1c564b3d53e6393ef184d32fb7e",
                "responses": {
                    "201": {
                        "description": "Created partner.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferPartner"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offer-partners/{id}": {
            "get": {
                "tags": [
                    "Offer Partner"
                ],
                "summary": "Offer Partner - Detail",
                "operationId": "81d77cbd719e26e15cc12fe6db5f2870",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Partner detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferPartner"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Offer Partner"
                ],
                "summary": "Offer Partner - Deactivate",
                "operationId": "6462447fe7a4f0a1fa97124cfb6c01d3",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferPartner"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Offer Partner"
                ],
                "summary": "Offer Partner - Update",
                "description": "Mutable: name, logo_url, contact_name, contact_email, contact_phone, offer_defaults. offer_defaults is set-wholesale (not deep-merged) on PATCH.",
                "operationId": "1a02cb4434ac4b95d7aac5ebbc4a953f",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferPartner"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers/{offer_id}/schedules": {
            "get": {
                "tags": [
                    "Offer Schedule"
                ],
                "summary": "Offer Schedule - List",
                "description": "All active windows for one offer, ordered by day_of_week then start_time. Unpaginated — typically 7-14 rows per offer.",
                "operationId": "c70dede3a59193bf2051110b223a85d4",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Schedule windows.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/OfferSchedule"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer Schedule"
                ],
                "summary": "Offer Schedule - Add Window",
                "description": "Body: day_of_week* (0-6, Sun-Sat), start_time* (HH:MM or HH:MM:SS), end_time* (HH:MM or HH:MM:SS). start_time must be strictly less than end_time (CHECK constraint mirrored here for a clean 422). Multiple windows per day are allowed — no uniqueness constraint on (offer_id, day_of_week).",
                "operationId": "bcf7320ffc14cbd1f80458e60cca21a5",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created window.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferSchedule"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Offer Schedule"
                ],
                "summary": "Offer Schedule - Clear All",
                "description": "Removes every schedule window for the offer. Leaves the offer with no schedule = inactive on all days until new windows are POSTed. Use to reset before re-populating from a template.",
                "operationId": "f32b75d818b95a76a7f35fb4b3fac508",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Cleared. data.removed = row count.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "removed": {
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/schedules/{schedule_id}": {
            "delete": {
                "tags": [
                    "Offer Schedule"
                ],
                "summary": "Offer Schedule - Remove Window",
                "description": "Removes one schedule window by id.",
                "operationId": "987368192d78acb02a04c885dd063c7f",
                "parameters": [
                    {
                        "name": "schedule_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "removed": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers/{offer_id}/zipcodes": {
            "get": {
                "tags": [
                    "Offer Zipcode"
                ],
                "summary": "Offer Zipcode - List",
                "description": "Paginated list of zipcodes allowlisted for this offer. NO rows = \"all US eligible\"; empty response is meaningful.",
                "operationId": "d0085578d545a96f7c8b620006dffdee",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 100,
                            "maximum": 500
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated zipcode list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "zipcode_id": {
                                                                "type": "integer"
                                                            },
                                                            "zipcode": {
                                                                "type": "string"
                                                            },
                                                            "date_added": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer Zipcode"
                ],
                "summary": "Offer Zipcode - Bulk Add",
                "description": "Body: {\"zipcode_ids\": [12345, 67890, ...]} — up to 10,000 per request. Ignored duplicates (ON CONFLICT DO NOTHING). Response reports how many were NEWLY added vs already-present.",
                "operationId": "da4a1125f1e7ccb0cfebceab1b6344c0",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "zipcode_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Bulk add applied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "requested": {
                                                            "type": "integer"
                                                        },
                                                        "inserted": {
                                                            "type": "integer"
                                                        },
                                                        "total": {
                                                            "description": "Total zipcode count for the offer after this operation.",
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure or bulk cap exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Offer Zipcode"
                ],
                "summary": "Offer Zipcode - Clear All",
                "description": "Removes all zipcode restrictions for the offer. After this, the offer becomes \"all US eligible\" (no rows in offer_zipcode = no gate).",
                "operationId": "d263f22c23ea68ab803af8ee9cc41c80",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Cleared.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "removed": {
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers": {
            "get": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - List",
                "description": "Paginated. Filters: q (substring on name), active, paused, offer_partner_id, priority_tier_id, test_mode.",
                "operationId": "8aa3eebacb992a6d6f5c48afa1035616",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "paused",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "test_mode",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "offer_partner_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "priority_tier_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "date_updated",
                                "priority_tier_id",
                                "tier_weight",
                                "payout",
                                "active",
                                "paused"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated offer list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Offer"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Create",
                "description": "Body: offer_partner_id*, name*, priority_tier_id*. All other fields optional with sensible defaults. offer_partner_id is IMMUTABLE post-create — pick carefully. FE pre-fills from offer_partner.offer_defaults before the POST (server does not auto-merge). All money as string.",
                "operationId": "99386a8df1e29ebb05dfbb8ed4ba5b78",
                "responses": {
                    "201": {
                        "description": "Created offer.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers/{id}": {
            "get": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Detail",
                "operationId": "eafe149307b9e65ebfcdead6a65c3057",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Offer detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Deactivate",
                "description": "Sets active=false. Never hard-deletes — historical impressions / clicks / conversions reference offer_id transitively via the funnel tables.",
                "operationId": "54adc19db427e7219307142fb43849d7",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Update",
                "description": "Partial update. Mutable: everything on the row EXCEPT offer_partner_id (immutable — see create). Use action endpoints for pause/resume/delete.",
                "operationId": "d8e87b21775c1cd8ccbe8ccff61d8f76",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers/{id}/pause": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Pause",
                "description": "Sets paused=true. Immediate effect on next matcher run — the `WHERE active AND NOT paused` predicate on the matcher's primary index excludes paused offers from every serve.",
                "operationId": "8352fdf38e525e570292dbf7bd559eb6",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paused.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers/{id}/resume": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Resume",
                "operationId": "08295a0c3f9cf95fcf3c272d39143bea",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resumed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers/{id}/reactivate": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Reactivate",
                "description": "Flips active=true on a previously-deactivated offer. Mirror of the DELETE endpoint. Also happens implicitly when an inactive offer is added to any offer_list via POST or PUT — this endpoint is for the case where ops wants to reactivate without touching list membership.",
                "operationId": "18639c81ff92ba750cec4a5465214153",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reactivated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Offer"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/offers/{id}/lists": {
            "get": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - List Memberships",
                "description": "Every offer_list this offer belongs to, with the junction row's weight/position/active plus the parent list's name for display. Powers the \"this offer appears in\" section on the offer detail page.",
                "operationId": "469c1ff7c86f86bcf6b230992a8f4671",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Memberships.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "offer_list_id": {
                                                                "type": "integer"
                                                            },
                                                            "name": {
                                                                "type": "string"
                                                            },
                                                            "weight": {
                                                                "type": "integer"
                                                            },
                                                            "position": {
                                                                "type": "integer",
                                                                "nullable": true
                                                            },
                                                            "active": {
                                                                "description": "Junction row active flag.",
                                                                "type": "boolean"
                                                            },
                                                            "list_active": {
                                                                "description": "Parent list active flag.",
                                                                "type": "boolean"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Set List Memberships (multi-select)",
                "description": "Sets exactly the given lists as this offer's memberships — additions and removals computed server-side. Supports the multi-select dropdown on the offer create/edit page: SPA sends {list_ids: [...]}, server diffs against current state and applies the deltas in one transaction. IMPLICIT REACTIVATION: if the offer is currently inactive AND the resulting membership set is non-empty, offer.active flips back to true.",
                "operationId": "0614546dd3d9511e5e416f598f56cb0c",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "list_ids": {
                                        "description": "Exact target set of offer_list_ids. Existing memberships not in this array are removed; new ones are added with weight=10, position=null.",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Set applied. Response includes the reconciliation summary.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "added": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "integer"
                                                            }
                                                        },
                                                        "removed": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "integer"
                                                            }
                                                        },
                                                        "unchanged": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "integer"
                                                            }
                                                        },
                                                        "reactivated": {
                                                            "description": "True iff this call flipped offer.active from false to true.",
                                                            "type": "boolean"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers": {
            "get": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - List",
                "description": "Paginated. Filters: q (name substring), active, paused, job_partner_id.",
                "operationId": "cd1f3ee495c95cd6a6b8b1fe802176f7",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "paused",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "job_partner_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "last_run_completed",
                                "active",
                                "paused",
                                "refresh_minutes"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated provider list. Each row carries `last_run_completed` — MAX(time_processing_finished) — for the providers-list badge.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Provider"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Create",
                "description": "Body: job_partner_id*, name*, feed_url, capture_node, username (write-only), password (write-only), refresh_minutes, schema_mapping (JSONB), click_id_param, fetch_method, fetch_config (JSONB), fetch_credentials (write-only).\n\n─── Fetch transport ────────────────────────────────────────\n`fetch_method` selects how the feed is acquired: `url` (default — HTTP(S)/FTP via feed_url, using username/password when set) or `s3` (S3 + STS AssumeRole).\n\nFor `s3`, `fetch_config` is REQUIRED and holds NON-SECRET config: `bucket`*, `key` or `prefix`, `region`, `role_arn`, `external_id`, `credential_source` (`instance` | `ssm` | `static`), `credentials_ref` (SSM path when source=ssm), `object_selection` (`key` | `newest_in_prefix`). It is returned in full on GET — none of it is a secret.\n\n`fetch_credentials` is a WRITE-ONLY object for the last-resort `static` path (`{\"access_key_id\": \"...\", \"secret_access_key\": \"...\"}`). It is AES-256-GCM encrypted at rest and NEVER returned by any GET — reads expose only the boolean `has_stored_credentials`. Prefer `credential_source: \"instance\"` so no credential exists at all.",
                "operationId": "cb99a5e79fc0ca2737ee4c495848d12e",
                "responses": {
                    "201": {
                        "description": "Created provider (detail shape — includes schema_mapping, campaign_count, latest_run, credential presence booleans; credential values never returned).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Provider"
                                                        },
                                                        {
                                                            "properties": {
                                                                "schema_mapping": {
                                                                    "type": "object",
                                                                    "nullable": true
                                                                },
                                                                "campaign_count": {
                                                                    "type": "integer"
                                                                },
                                                                "username_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "password_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "latest_run": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/RunInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure (includes fetch_config shape errors).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers/{id}": {
            "get": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Detail",
                "operationId": "24af9a2947b6d6be885f40eb883542f7",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Provider detail — list-row fields + schema_mapping + campaign_count + credential presence booleans + latest_run.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Provider"
                                                        },
                                                        {
                                                            "properties": {
                                                                "schema_mapping": {
                                                                    "type": "object",
                                                                    "nullable": true
                                                                },
                                                                "campaign_count": {
                                                                    "type": "integer"
                                                                },
                                                                "username_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "password_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "latest_run": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/RunInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Deactivate",
                "description": "Never hard-deletes — historical clicks and run_info rows need the FK target to survive.",
                "operationId": "70816c55775230ac0dda6d1bf07029d7",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated provider (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Provider"
                                                        },
                                                        {
                                                            "properties": {
                                                                "schema_mapping": {
                                                                    "type": "object",
                                                                    "nullable": true
                                                                },
                                                                "campaign_count": {
                                                                    "type": "integer"
                                                                },
                                                                "username_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "password_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "latest_run": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/RunInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Update",
                "description": "Partial update — config fields only. Accepts any subset of: name, feed_url, capture_node, username, password, refresh_minutes, schema_mapping, click_id_param, job_partner_id, fetch_method, fetch_config, fetch_credentials. To toggle pause/resume/active-state, use the dedicated action endpoints.\n\n`fetch_config` REPLACES the stored object wholesale — send the complete config, not a partial patch. When `fetch_method` is present the config is validated against the new method; when it is absent the CURRENT stored method is used, so you can PATCH config alone without restating the method.\n\nSend `fetch_credentials: null` to CLEAR stored credentials (the correct move after switching a provider to `credential_source: \"instance\"`). Omitting the field leaves them untouched.",
                "operationId": "11b1abb66a41c46e6561e3fcf75a4d36",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated provider (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Provider"
                                                        },
                                                        {
                                                            "properties": {
                                                                "schema_mapping": {
                                                                    "type": "object",
                                                                    "nullable": true
                                                                },
                                                                "campaign_count": {
                                                                    "type": "integer"
                                                                },
                                                                "username_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "password_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "latest_run": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/RunInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers/{id}/sample-job": {
            "get": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Sample Job (Solr preview)",
                "description": "Pulls ONE currently-indexed job for this provider straight from Solr, for a live preview of what the provider's ingested jobs look like — the FULL document (description HTML, cpc, joburl, hashes, etc.), not the consumer-facing projection, since this is an operator tool. Also returns `total_indexed` so the operator sees how many jobs the provider has in the index.\n\n─── Which job ──────────────────────────────────────────────\nDefault: the most recently posted job (`date_posted desc, id asc`). Pass `solr_id` to preview one specific document, or `q` to preview the top job matching a keyword (full-text within this provider only). `solr_id` and `q` are mutually exclusive — `solr_id` wins if both are sent.\n\nReturns `job: null` (still 200) when the provider has nothing indexed yet, or when a supplied `solr_id` doesn't exist / belongs to a different provider.",
                "operationId": "77e5834b0032edec7795d69605d97faa",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "solr_id",
                        "in": "query",
                        "description": "Preview this exact Solr document id (\"{provider}_{jobid}\"). Must belong to this provider.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Preview the top job matching this keyword (scoped to this provider). Ignored when solr_id is present.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The sampled job (or job=null when none matched). `job` is the raw Solr document minus Solr-internal fields (_version_, _root_, score).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "job": {
                                                            "description": "Full Solr document (all stored fields), or null when nothing matched.",
                                                            "type": "object",
                                                            "nullable": true,
                                                            "additionalProperties": true
                                                        },
                                                        "total_indexed": {
                                                            "description": "Count of documents this provider currently has in Solr.",
                                                            "type": "integer"
                                                        },
                                                        "query": {
                                                            "description": "The effective full-text query used (\"*:*\" for the default newest-job pull); null when solr_id targeting was used.",
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "solr_id": {
                                                            "description": "Echo of the requested solr_id, when one was supplied.",
                                                            "type": "string",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Provider not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Solr query failed (index down / unreachable).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers/{id}/pause": {
            "post": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Pause",
                "description": "Sets paused=true. Takes ~2 minutes to affect live search (cache refresh cadence).",
                "operationId": "3277c22ffec66759c03cfb1c6a8aaacd",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paused provider (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Provider"
                                                        },
                                                        {
                                                            "properties": {
                                                                "schema_mapping": {
                                                                    "type": "object",
                                                                    "nullable": true
                                                                },
                                                                "campaign_count": {
                                                                    "type": "integer"
                                                                },
                                                                "username_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "password_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "latest_run": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/RunInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers/{id}/resume": {
            "post": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Resume",
                "description": "Sets paused=false. Takes ~2 minutes to affect live search.",
                "operationId": "45a483931c52d91b888207c0438a5364",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resumed provider (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Provider"
                                                        },
                                                        {
                                                            "properties": {
                                                                "schema_mapping": {
                                                                    "type": "object",
                                                                    "nullable": true
                                                                },
                                                                "campaign_count": {
                                                                    "type": "integer"
                                                                },
                                                                "username_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "password_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "latest_run": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/RunInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers/{id}/force-run": {
            "post": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Force Run",
                "description": "Sets force_run=true. The feed:dispatch scheduler picks it up on the next tick (~1 min). Returns 202 — the run is not immediate.",
                "operationId": "8d1bbfbe380107703ab11044bb0bc987",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Accepted — dispatcher will pick up shortly. Asynchronous, in contrast to schema/init which is synchronous.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "force_run_scheduled": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers/{id}/schema/init": {
            "post": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Init Schema",
                "description": "Runs SchemaAutoMapper against the first <capture_node> in a feed sample. Returns the suggested mapping. Pass `{\"save\": true}` to also persist it into sponsor.job_provider.schema_mapping. HTTP mirror of the `php spark feed:init <id> [--save]` command.\n\n─── Cached-sample behavior (default) ─────────────────────────\nBy default this endpoint REUSES the most recent locally-cached XML file for the provider if one exists and is under `max_age_hours` old (default 24h). This keeps iterative \"adjust capture_node → re-init → adjust → re-init\" workflows from burning a fresh download every time. If no cached file exists or the file is too old, falls through to a fresh fetch automatically.\n\nPass `{\"force_download\": true}` to skip the cache and always fetch fresh. The response includes `used_cached_file` so the SPA can surface which path ran.\n\n─── Timing ──────────────────────────────────────────────────\nSynchronous. Cached-sample path returns in seconds (parse-only). Fresh-fetch path can run 30-120s depending on feed size — surface a loading state in the SPA when force_download or when no cache exists yet.\n\n─── Warnings (READ THESE) ──────────────────────────────────\nThe response includes a `warnings` array of advisory strings. Each one means a field will be missing or wrong after ingest:\n  • a mapping landed at \"suggested\" confidence — the transform step SKIPS those, so the field is empty on every document\n  • a required target (jobid, title, description, joburl, company, city, state, date_posted) has no source at all\n  • the sample contains a self-nested element, which is unsafe to use as capture_node\nSurface these prominently in the SPA — an empty array is the \"good to process\" signal. Warnings are advisory and are NOT persisted into schema_mapping when save=true.\n\n─── Failure modes ──────────────────────────────────────────\n404 (provider not found), 422 (no feed_url configured), 502 (fetch or parse failed — check feed log for details).",
                "operationId": "90030c1bfc8edc849cd00c2bf47cd00d",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "save": {
                                        "description": "Persist the mapping to sponsor.job_provider.schema_mapping.",
                                        "type": "boolean",
                                        "default": false
                                    },
                                    "force_download": {
                                        "description": "Skip the local-cache check and always re-fetch. Use when the feed content has changed but the cache is still fresh.",
                                        "type": "boolean",
                                        "default": false
                                    },
                                    "max_age_hours": {
                                        "description": "Max age (hours) for the cached XML file to be usable. Ignored when force_download=true.",
                                        "type": "integer",
                                        "default": 24
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Mapping generated. Synchronous — the response includes the suggested mapping directly. NOTE: 200 not 202 (unlike force-run, which is async).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "suggested_mapping": {
                                                            "description": "Field-to-source map inferred from the feed sample.",
                                                            "type": "object"
                                                        },
                                                        "saved": {
                                                            "description": "True iff save=true was passed AND the DB write succeeded.",
                                                            "type": "boolean"
                                                        },
                                                        "used_cached_file": {
                                                            "description": "True when the fresh-fetch path was skipped in favor of a cached XML sample.",
                                                            "type": "boolean"
                                                        },
                                                        "warnings": {
                                                            "description": "Empty = \"good to process\". Non-empty rows describe fields that will be missing or wrong after ingest.",
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            }
                                                        },
                                                        "save_error": {
                                                            "description": "Present only when save=true but the DB write failed. Mapping still returned so the caller can retry the save.",
                                                            "type": "string"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Provider not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Provider has no feed_url configured.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Feed fetch or XML parse failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/providers/{id}/activate": {
            "post": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - Activate",
                "description": "Reactivates a provider that was soft-deactivated via DELETE — sets active=true. The inverse of DELETE /providers/{id}. Kept as a dedicated action (not PATCH) so the deactivate/reactivate pair stays out of config-edit audit noise. Takes ~2 minutes to affect live search (cache refresh cadence). Note: this does NOT touch `paused` — a provider that was paused before deactivation comes back still paused; resume it separately if needed.",
                "operationId": "e19ff8c34e298256a1687da5048160f5",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reactivated provider (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Provider"
                                                        },
                                                        {
                                                            "properties": {
                                                                "schema_mapping": {
                                                                    "type": "object",
                                                                    "nullable": true
                                                                },
                                                                "campaign_count": {
                                                                    "type": "integer"
                                                                },
                                                                "username_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "password_set": {
                                                                    "type": "boolean"
                                                                },
                                                                "latest_run": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/RunInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/publishers/{id}/accounts": {
            "get": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - List",
                "description": "Returns prefix + hint (never plaintext or hash). Unpaginated — a publisher typically has a small number of keys (rotate + revoke pattern).",
                "operationId": "07005add1dbb5705ae2d91d1457fef5b",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "account_name",
                                "date_created",
                                "date_last_used",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Accounts list (unpaginated — small per publisher).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PublisherAccount"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Publisher not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Create",
                "description": "Generates a fresh key via PublisherAccountManager, INSERTs the hash + prefix + hint into publisher_account, and returns the plaintext IN THE RESPONSE BODY exactly once. The plaintext is unrecoverable after this call — the SPA MUST force a \"copy this key\" confirmation step before the modal closes. Body: account_name*, cpc_share (default 0.7000), rate_limit_tier (default 'default'), organic (default false).",
                "operationId": "12c20d0f82c664127037e7a6fbab09c4",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "account_name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "cpc_share": {
                                        "type": "number",
                                        "format": "float",
                                        "default": 0.7,
                                        "maximum": 1,
                                        "minimum": 0
                                    },
                                    "rate_limit_tier": {
                                        "type": "string",
                                        "default": "default",
                                        "maxLength": 32
                                    },
                                    "organic": {
                                        "description": "Mix unpaid / organic inventory into this account's search results (below paid). Default false.",
                                        "type": "boolean",
                                        "default": false
                                    },
                                    "min_payout": {
                                        "description": "Minimum NET payout (effective_cpc x cpc_share) this account earns on a served paid job. Paid jobs below it are not served to this account on the live search API; organic backfill is unaffected. Null / omitted = no floor.",
                                        "type": "number",
                                        "format": "float",
                                        "nullable": true,
                                        "minimum": 0
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created. `data.api_key_plaintext` is returned EXACTLY ONCE — unrecoverable after this response. `data.warning` explains this to the user.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/PublisherAccount"
                                                        },
                                                        {
                                                            "properties": {
                                                                "api_key_plaintext": {
                                                                    "description": "The full plaintext key. Returned once, never again. Store immediately.",
                                                                    "type": "string"
                                                                },
                                                                "warning": {
                                                                    "type": "string"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Publisher not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/accounts/{account_id}": {
            "patch": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Update",
                "description": "Mutable: account_name, cpc_share, rate_limit_tier, organic, min_payout (number = net payout floor for live serving; null clears it). The key material itself is immutable — rotate by revoking and issuing new.",
                "operationId": "fff54f28fa1d8fd106d669b3d465f0bf",
                "parameters": [
                    {
                        "name": "account_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherAccount"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/accounts/{account_id}/revoke": {
            "post": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Revoke",
                "description": "Sets active=false. PublisherAuth denies the key on the very next request — no cache warmup delay because the auth check is a per-request DB lookup. Historical clicks attributed to this account keep their FK.",
                "operationId": "0322f6b95002d6f420e61d7b0c1d46b4",
                "parameters": [
                    {
                        "name": "account_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Revoked account (active=false).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherAccount"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/accounts/{account_id}/regenerate": {
            "post": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Regenerate Key",
                "description": "Rotates key material IN PLACE on the same publisher_account row. Same semantics as the self-serve /publisher/v1/api-keys/{id}/regenerate — account (name, cpc_share, tier, historical click attribution) preserved; prefix/hash/hint replaced. Old key stops authenticating IMMEDIATELY. Plaintext returned EXACTLY ONCE. Admin-initiated rotations log actor_type='admin' on publisher.publisher_key_rotation.",
                "operationId": "5b156616af43993e1f9784b5f3e30845",
                "parameters": [
                    {
                        "name": "account_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Rotated. `data.api_key_plaintext` is returned exactly once.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/PublisherAccount"
                                                        },
                                                        {
                                                            "properties": {
                                                                "api_key_plaintext": {
                                                                    "type": "string"
                                                                },
                                                                "warning": {
                                                                    "type": "string"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Prefix collision on generation (pathologically rare).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/accounts/{account_id}/rotations": {
            "get": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Rotation History",
                "description": "Paginated list of every rotate/revoke/reactivate/expire event on this account, newest first. Each row includes `actor_display` — the human-readable \"First Last (username)\" of the admin or publisher-login who initiated it, or \"system\" for automated events.",
                "operationId": "c2a2ef4eb1ceb944ebf2c41bf799094a",
                "parameters": [
                    {
                        "name": "account_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated rotation history.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PublisherKeyRotation"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/accounts/{account_id}/reactivate": {
            "post": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Reactivate",
                "description": "Flips active=true on a previously-revoked account. Admin-only — publishers cannot self-serve reactivate (a revoked key is off for a reason). PublisherAuth starts accepting the key again immediately (next request lookup returns active=true). Logs actor_type='admin' on publisher.publisher_key_rotation.",
                "operationId": "462b77000f5ee53b8bd0fd812abc379f",
                "parameters": [
                    {
                        "name": "account_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reactivated account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherAccount"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/publisher-logins": {
            "get": {
                "tags": [
                    "Publisher Login"
                ],
                "summary": "Publisher Login - List",
                "operationId": "fd86e3c59eb6460d320a1629a65ea2fe",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "publisher_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "username",
                                "first_name",
                                "last_name",
                                "email",
                                "date_created",
                                "date_last_login",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated publisher-login list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PublisherLogin"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Publisher Login"
                ],
                "summary": "Publisher Login - Create",
                "description": "Body: username*, password*, email*, publisher_id*, first_name, last_name, phone.",
                "operationId": "1b82c248a89a6de5df4e5643fc7d8e23",
                "responses": {
                    "201": {
                        "description": "Created publisher login.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Username or email already taken.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/publisher-logins/{id}": {
            "get": {
                "tags": [
                    "Publisher Login"
                ],
                "summary": "Publisher Login - Detail",
                "operationId": "2f4bb3e624bf967118f451e400456eb6",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Publisher login detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Publisher Login"
                ],
                "summary": "Publisher Login - Deactivate",
                "operationId": "21bffda982457820917d56894d575305",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated publisher login.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Publisher Login"
                ],
                "summary": "Publisher Login - Update",
                "description": "Partial update (non-secret fields). Mutable: first_name, last_name, email, phone, publisher_id.",
                "operationId": "21334482b80389d85da48fef2f5fac27",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated publisher login.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/publisher-logins/{id}/reset-password": {
            "post": {
                "tags": [
                    "Publisher Login"
                ],
                "summary": "Publisher Login - Reset Password",
                "operationId": "4e43cea011e5beafac6345c990e95146",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Password reset succeeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "reset": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Password too short.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/publishers": {
            "get": {
                "tags": [
                    "Publisher"
                ],
                "summary": "Publisher - List",
                "operationId": "a9738404a8d2db22f74d1c384c21c5a3",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated publisher list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Publisher"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Publisher"
                ],
                "summary": "Publisher - Create",
                "description": "Body: name*, website, city, state, postal, country, address1, address2, primary_contact, primary_email, primary_phone. All optional except name.",
                "operationId": "be80c36ae1d6cc324d35c6a15069b0fd",
                "responses": {
                    "201": {
                        "description": "Created publisher (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Publisher"
                                                        },
                                                        {
                                                            "properties": {
                                                                "accounts": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/PublisherAccount"
                                                                    }
                                                                },
                                                                "earnings_summary": {
                                                                    "$ref": "#/components/schemas/EarningsSummary"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/publishers/{id}": {
            "get": {
                "tags": [
                    "Publisher"
                ],
                "summary": "Publisher - Detail",
                "operationId": "2d438b025827928dad8b62b33fee369d",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Publisher detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Publisher"
                                                        },
                                                        {
                                                            "properties": {
                                                                "accounts": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/PublisherAccount"
                                                                    }
                                                                },
                                                                "earnings_summary": {
                                                                    "$ref": "#/components/schemas/EarningsSummary"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Publisher"
                ],
                "summary": "Publisher - Deactivate",
                "operationId": "8cf05a9fba95e96e7e32db52f246af5a",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated publisher (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Publisher"
                                                        },
                                                        {
                                                            "properties": {
                                                                "accounts": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/PublisherAccount"
                                                                    }
                                                                },
                                                                "earnings_summary": {
                                                                    "$ref": "#/components/schemas/EarningsSummary"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Publisher"
                ],
                "summary": "Publisher - Update",
                "description": "Partial update. Mutable: name, address1/2, city, state, postal, country, website, primary_contact, primary_email, primary_phone. Use DELETE for deactivation.",
                "operationId": "dbdc326845a80045cd278f98cf29f454",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated publisher (detail shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Publisher"
                                                        },
                                                        {
                                                            "properties": {
                                                                "accounts": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "$ref": "#/components/schemas/PublisherAccount"
                                                                    }
                                                                },
                                                                "earnings_summary": {
                                                                    "$ref": "#/components/schemas/EarningsSummary"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/reports/clicks": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Clicks",
                "description": "Daily click aggregates. Admin sees system-wide; narrow with any subset of publisher_id, publisher_account_id, sponsor_id, job_provider_id. Sourced from click_publisher_daily_rollup; refreshed every ~5 minutes by clicks:refresh-rollups. Group by date, account, publisher, provider.",
                "operationId": "bab3312aa93ed8f86be313d5e53b1de5",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "publisher_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "publisher_account_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sponsor_id",
                        "in": "query",
                        "schema": {
                            "description": "aka job_partner_id",
                            "type": "integer"
                        }
                    },
                    {
                        "name": "job_provider_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. Id filters accept a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportClicksDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/reports/spend": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Spend",
                "description": "Daily spend aggregates, sponsor-flavored. Admin sees system-wide; narrow with sponsor_id (job_partner_id), job_provider_id, or campaign_id. Sourced from click_sponsor_daily_rollup. Group by date, campaign, provider, segment, sponsor.",
                "operationId": "445d555f6194bfe1fc2dc034fecdade4",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "sponsor_id",
                        "in": "query",
                        "schema": {
                            "description": "aka job_partner_id",
                            "type": "integer"
                        }
                    },
                    {
                        "name": "job_provider_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "campaign_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. Id filters accept a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportSpendDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/reports/earnings": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Earnings",
                "description": "Daily share-adjusted earnings, publisher-flavored. Admin sees system-wide; narrow with publisher_id or publisher_account_id. Uses the snapshotted publisher_earnings on the rollup (share applied at roll time), so a later cpc_share change does not re-rate closed history. Group by date, account, publisher, provider.",
                "operationId": "71921fecae09848795fb76b811fe3afb",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "publisher_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "publisher_account_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "job_provider_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. Id filters accept a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportEarningsDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/reports/api-usage": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - API Usage",
                "description": "Daily API-request aggregates over publisher.api_request_log. Admin sees all publisher traffic; narrow with publisher_id or publisher_account_id. Query hits the monthly-partitioned request log — wide ranges cross partition boundaries but stay indexed on created_at. Group by date, account, publisher.",
                "operationId": "e5b64fb9fdb858b95c717f11f2f7bfec",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "publisher_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "publisher_account_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. Id filters accept a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportApiUsageDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/reports/offers": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Offers",
                "description": "Daily offer-funnel aggregates (impressions -> clicks -> conversions -> payout) from offer.offer_daily_rollup (refreshed every ~5 min by offers:refresh-rollups). Admin-only. Narrow with offer_id or offer_partner_id.",
                "operationId": "2dc56d2c872594cf30532ca324df4381",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "offer_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offer_partner_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat/CSV): date, offer, partner. Default date. Id filters accept a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportOffersDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/segments/{segment_id}": {
            "delete": {
                "tags": [
                    "Segment"
                ],
                "summary": "Segment - Deactivate",
                "description": "Sets active=false. Segments retain their row for audit continuity — historical clicks that matched a segment need the FK target to survive.",
                "operationId": "7c4fb2bc31007008770ecc34da4be26f",
                "parameters": [
                    {
                        "name": "segment_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated segment.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Segment"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Segment"
                ],
                "summary": "Segment - Update",
                "description": "Mutable: name, criteria (JSONB), bid_low, bid_high, prefer_high_bid, active, and (CPA campaigns) conversion_rate_assumed, effective_cpc_override, observation_tuning_enabled. Editing any rate field re-derives the read-only conversion_rate_working. bid_low must be >= 0 and bid_high >= bid_low (enforced by both this endpoint and the DB CHECK).",
                "operationId": "34d2d95a90d57ffeaf6ade1bd057c93f",
                "parameters": [
                    {
                        "name": "segment_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated segment.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Segment"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/segments/{segment_id}/observations": {
            "get": {
                "tags": [
                    "Segment"
                ],
                "summary": "Segment - Conversion Observations",
                "description": "Per-day CPA conversion time series for a segment (sponsor.segment_conversion_observation) — the source for the CPA performance graph. Returns clicks, confirmed conversions, the (capped) daily observed rate, and confirmed revenue per day, newest first. Defaults to the last 30 days; bound with from/to (YYYY-MM-DD).",
                "operationId": "208d25acd79f2f51564c8dee9e154707",
                "parameters": [
                    {
                        "name": "segment_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Observation rows (money + rate as exact DB strings).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "properties": {
                                                            "report_date": {
                                                                "type": "string",
                                                                "format": "date"
                                                            },
                                                            "clicks": {
                                                                "type": "integer"
                                                            },
                                                            "conversions": {
                                                                "type": "integer"
                                                            },
                                                            "observed_rate": {
                                                                "type": "string",
                                                                "example": "0.037500",
                                                                "nullable": true
                                                            },
                                                            "revenue_confirmed": {
                                                                "type": "string",
                                                                "example": "1875.00"
                                                            }
                                                        },
                                                        "type": "object"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Segment not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/sponsor-logins": {
            "get": {
                "tags": [
                    "Sponsor Login"
                ],
                "summary": "Sponsor Login - List",
                "operationId": "28019d97d9cc891c667b4a6033f622ce",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "job_partner_id",
                        "in": "query",
                        "description": "Parent sponsor org.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "job_provider_id",
                        "in": "query",
                        "description": "Sub-account provider scope; nullable in the underlying row.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "username",
                                "first_name",
                                "last_name",
                                "email",
                                "date_created",
                                "date_last_login",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated sponsor-login list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/SponsorLogin"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Sponsor Login"
                ],
                "summary": "Sponsor Login - Create",
                "description": "Body: username*, password*, email*, job_partner_id*, first_name, last_name, phone, job_provider_id (optional — omit for org-wide access, set for sub-account scoping to a specific provider under the partner).",
                "operationId": "5833623de27cf25f4ce900a24f1a8d27",
                "responses": {
                    "201": {
                        "description": "Created sponsor login.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/SponsorLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Username or email already taken.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/sponsor-logins/{id}": {
            "get": {
                "tags": [
                    "Sponsor Login"
                ],
                "summary": "Sponsor Login - Detail",
                "operationId": "7c2ed4859b2e925f3cb5b1ba7d48b5c5",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sponsor login detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/SponsorLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Sponsor Login"
                ],
                "summary": "Sponsor Login - Deactivate",
                "operationId": "b04e788d13b60f0a70b44a965c6b9d18",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated sponsor login.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/SponsorLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Sponsor Login"
                ],
                "summary": "Sponsor Login - Update",
                "description": "Partial update (non-secret fields). Mutable: username, first_name, last_name, email, phone, job_partner_id, job_provider_id. Reassigning to a different job_partner is allowed but clears job_provider_id automatically (a provider under one partner can't belong to another). Changing username to one already used by another active login returns 409.",
                "operationId": "12ae9cd4686783dc11033885f29e540e",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated sponsor login.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/SponsorLogin"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Username already in use by another active login.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/sponsor-logins/{id}/reset-password": {
            "post": {
                "tags": [
                    "Sponsor Login"
                ],
                "summary": "Sponsor Login - Reset Password",
                "operationId": "a9c65cc282ef73d9f68e569f77648782",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Password reset succeeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "reset": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Password too short.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/sponsors/{id}/callback-key": {
            "post": {
                "tags": [
                    "Sponsor"
                ],
                "summary": "Sponsor - Generate Callback Key",
                "description": "Generates (or REGENERATES, invalidating the old one) this sponsor's conversion-callback key — the Bearer credential the sponsor presents on POST api.juju.com/api/v1/conversions. ONE key covers every provider/feed the sponsor runs (the click_id in the postback resolves the specific provider on its own). The plaintext is returned ONCE here and never again (only a hash is stored); relay it to the sponsor securely. Regenerating immediately breaks any callback still using the previous key.",
                "operationId": "6ccbbea96fb4bd3efd67168b6dce5e32",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "New callback key. `plaintext` is shown only in this response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "plaintext": {
                                                            "description": "Full key — shown once, store securely.",
                                                            "type": "string",
                                                            "example": "juju_cb_Xy7...q2"
                                                        },
                                                        "hint": {
                                                            "description": "Last 4 chars, echoed in future GETs to identify the key.",
                                                            "type": "string",
                                                            "example": "q2Rk"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Sponsor not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/sponsors": {
            "get": {
                "tags": [
                    "Sponsor"
                ],
                "summary": "Sponsor - List",
                "description": "Paginated. Filters: q (substring against name), active. `Sponsor` = the parent org that owns Providers — every Provider row carries `job_partner_id` FK to this table. UI-facing term is \"Sponsor\"; the underlying table is sponsor.job_partner for historical reasons (predates the sponsor schema).",
                "operationId": "90bd89b1a9d818f7f13fdf895e4c13f1",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "name",
                                "date_created",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated sponsor list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Sponsor"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Sponsor"
                ],
                "summary": "Sponsor - Create",
                "description": "Body: name*, website, documentation.",
                "operationId": "5200e743eed2c769cef2628794898bc0",
                "responses": {
                    "201": {
                        "description": "Created sponsor. `data` is the same shape as GET /sponsors/{id}.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Sponsor"
                                                        },
                                                        {
                                                            "properties": {
                                                                "provider_count": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/sponsors/{id}": {
            "get": {
                "tags": [
                    "Sponsor"
                ],
                "summary": "Sponsor - Detail",
                "description": "Includes provider_count (count of active providers under this sponsor).",
                "operationId": "2dca1115f8f7dcb66d7fdd65329b2967",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sponsor detail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Sponsor"
                                                        },
                                                        {
                                                            "properties": {
                                                                "provider_count": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Sponsor"
                ],
                "summary": "Sponsor - Deactivate",
                "description": "Sets active=false. Never hard-deletes — providers under this sponsor keep their FK target intact, and historical clicks/runs need the row to survive.",
                "operationId": "61b8d9ab5efa9e51e93424a3290b5f46",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated sponsor.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Sponsor"
                                                        },
                                                        {
                                                            "properties": {
                                                                "provider_count": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Sponsor"
                ],
                "summary": "Sponsor - Update",
                "description": "Mutable: name, website, documentation. Use DELETE for deactivation.",
                "operationId": "5765983fa62639768ac4638cc1b6c12a",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated sponsor.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/Sponsor"
                                                        },
                                                        {
                                                            "properties": {
                                                                "provider_count": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/system/budget-status": {
            "get": {
                "tags": [
                    "System"
                ],
                "summary": "System - Budget Status",
                "description": "Campaign-cache health probe (admin-scoped mirror of the public endpoint). Same body shape as GET /api/v1/jobs/budget-status. Provided on the admin surface so admin dashboards don't have to reach across into the public tier. Alert-worthy fields: stale_warning=true (refresh task stopped firing) and live_providers=false (/jobs/search is currently returning empty).",
                "operationId": "77a12e689edb9b50e77fc6db080fe864",
                "responses": {
                    "200": {
                        "description": "Read the body fields to determine cache health.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/system/provider-status": {
            "get": {
                "tags": [
                    "System"
                ],
                "summary": "System - Provider Status",
                "description": "Per-provider serving + budget + inventory report for the admin dashboard. Shows which providers are currently serving (paid / organic), each active campaign's remaining budget, and how many jobs the provider has in the Solr index. Serving state + spend are free reads of the sponsor:refresh-budgets cache (money is NOT recomputed here); job counts come fresh from Solr. `meta.refresh_stale=true` means sponsor:refresh-budgets has stopped firing and the serving/spend numbers are stale. Optional `provider` query param limits to one job_provider_id. Money as strings.",
                "operationId": "986b0f471e18ac5e7bd3c2b1b0c66d23",
                "parameters": [
                    {
                        "name": "provider",
                        "in": "query",
                        "description": "Limit to a single job_provider_id.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Provider status report.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ProviderStatus"
                                                    }
                                                },
                                                "meta": {
                                                    "properties": {
                                                        "refresh_age_seconds": {
                                                            "description": "Seconds since the last sponsor:refresh-budgets tick, or null if never.",
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "refresh_stale": {
                                                            "description": "True when the refresh is older than 300s (or absent) — serving/spend numbers are stale.",
                                                            "type": "boolean"
                                                        },
                                                        "solr_error": {
                                                            "description": "Non-null when the Solr job-count query failed; job counts then read 0.",
                                                            "type": "string",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/system/health-summary": {
            "get": {
                "tags": [
                    "System"
                ],
                "summary": "System - Health Summary",
                "description": "One-screen platform health report. Aggregates individual health probes across the platform's core dependencies. Every field is best-effort — a failed probe yields {up: false} for that block rather than 500ing the whole endpoint. Use for the admin dashboard's \"is the platform healthy?\" widget and for external monitoring integration.",
                "operationId": "8f11785e7ef15ebbd4fb77105a6068a2",
                "responses": {
                    "200": {
                        "description": "Health summary.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "solr": {
                                                            "properties": {
                                                                "up": {
                                                                    "type": "boolean"
                                                                },
                                                                "document_count": {
                                                                    "type": "integer",
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "memcached": {
                                                            "properties": {
                                                                "up": {
                                                                    "type": "boolean"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "postgres": {
                                                            "properties": {
                                                                "up": {
                                                                    "type": "boolean"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "feed_worker": {
                                                            "properties": {
                                                                "last_run_completed": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true
                                                                },
                                                                "runs_active": {
                                                                    "type": "integer"
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "budget_refresh": {
                                                            "properties": {
                                                                "last_run": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true
                                                                },
                                                                "stale_warning": {
                                                                    "type": "boolean"
                                                                },
                                                                "refresh_age_seconds": {
                                                                    "type": "integer",
                                                                    "nullable": true
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/users": {
            "get": {
                "tags": [
                    "User"
                ],
                "summary": "User - List",
                "description": "Paginated. Filters: q (substring on email/first_name/last_name), active, verified (based on date_verified on the email artifact), created_since (ISO date).",
                "operationId": "ec4df2da880a6498ea2c2085dd7b3f6d",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "verified",
                        "in": "query",
                        "description": "true = e.date_verified IS NOT NULL; false = IS NULL",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "created_since",
                        "in": "query",
                        "description": "ISO 8601 lower bound on juju.user.date_created.",
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "email",
                                "first_name",
                                "last_name",
                                "date_created",
                                "date_verified",
                                "date_last_login",
                                "active"
                            ]
                        }
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated user list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ConsumerUser"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/users/{id}": {
            "get": {
                "tags": [
                    "User"
                ],
                "summary": "User - Detail",
                "description": "Enriched view for support / ops drill-down. Includes extended PII (juju.user_info) and activity counts (saved_jobs, saved_searches, recent search history, recent clicks). Click count is bounded to the last 90 days — jobs.click is time-partitioned and an unbounded COUNT would scan every partition.",
                "operationId": "ccce052a88673d24ebd43c78e6299764",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "User detail — list-row fields + `info` (nullable UserInfo) + `activity`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/ConsumerUser"
                                                        },
                                                        {
                                                            "properties": {
                                                                "info": {
                                                                    "oneOf": [
                                                                        {
                                                                            "$ref": "#/components/schemas/UserInfo"
                                                                        }
                                                                    ],
                                                                    "nullable": true
                                                                },
                                                                "activity": {
                                                                    "$ref": "#/components/schemas/UserActivity"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/users/{id}/deactivate": {
            "post": {
                "tags": [
                    "User"
                ],
                "summary": "User - Deactivate",
                "description": "Immediate effect on next request: session_auth finds the JWT valid but Profile's row lookup filters WHERE active=true and returns null → 401. Row is preserved for billing / audit continuity.",
                "operationId": "35b1ba05a6d67c47354cc06119af2277",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deactivated user (list-row shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ConsumerUser"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/users/{id}/reactivate": {
            "post": {
                "tags": [
                    "User"
                ],
                "summary": "User - Reactivate",
                "operationId": "0fc421669b8ca12a3d53536dd6bafeb9",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reactivated user (list-row shape).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/ConsumerUser"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/admin/v1/users/purge-stale": {
            "post": {
                "tags": [
                    "User"
                ],
                "summary": "User - Purge Stale Data",
                "description": "Runs the same retention DELETEs the `users:purge-stale-data` spark command runs. Synchronous — the endpoint waits for the DELETEs to complete and returns row counts. Body: `{\"dry_run\": bool, \"target\": \"all|saved-jobs|search-history\"}`. Retention policy: saved_job 3y unapplied / 7y applied, search_history 90d.",
                "operationId": "b2631ad173291fa419478c7b9b6cb524",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "dry_run": {
                                        "type": "boolean",
                                        "default": false
                                    },
                                    "target": {
                                        "type": "string",
                                        "default": "all",
                                        "enum": [
                                            "all",
                                            "saved-jobs",
                                            "search-history"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Purge complete. `data` reports what was (or would have been) deleted per target.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "dry_run": {
                                                            "type": "boolean"
                                                        },
                                                        "target": {
                                                            "type": "string",
                                                            "enum": [
                                                                "all",
                                                                "saved-jobs",
                                                                "search-history"
                                                            ]
                                                        },
                                                        "saved_jobs_deleted": {
                                                            "description": "Null when target excludes this bucket.",
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "search_history_deleted": {
                                                            "type": "integer",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/jobs/click/{token}": {
            "get": {
                "tags": [
                    "Clicks"
                ],
                "summary": "Click-through redirector for job applications",
                "description": "Decodes an AES-CTR token (produced by JobDocumentFormatter as the `click_url` field on every search/show response), records an attribution row in jobs.click, snapshots the job's display fields for forensics, and 302-redirects the user to the underlying provider URL. NOT under /api/v1 — these URLs end up in emails, shared links, and search-engine caches, so they stay short and stable across API version bumps. ALWAYS hit this URL to send a user to a job — direct provider URLs are intentionally not exposed.",
                "operationId": "6643e4109ffee94bb735997bc6206210",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "description": "AES-256-CTR-encrypted base64url token from a Job document's `click_url` field. Opaque to consumers — never construct this client-side, only pass through verbatim.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "302": {
                        "description": "Successful click. `Location` header carries the underlying provider URL (with any provider-configured tracking parameters appended). The browser follows it automatically.",
                        "headers": {
                            "Location": {
                                "description": "The provider URL to redirect to.",
                                "schema": {
                                    "type": "string",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Missing token path parameter.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "410": {
                        "description": "Token decryption failed, the underlying job has expired / been deleted, or its joburl is unavailable. The link is permanently dead — do NOT retry.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Solr lookup failed — the underlying job document could not be fetched, so there is no destination to send the user to. Retry with backoff is OK. NOTE: a failed click-INSERT no longer 503s; the user is 302-redirected to the job anyway and the billing miss is logged (see the 302 response).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/conversions/college-recruiter": {
            "post": {
                "tags": [
                    "Conversions"
                ],
                "summary": "College Recruiter conversion webhook (HMAC-signed)",
                "description": "Partner-specific conversion callback for College Recruiter, who authenticates by HMAC signature rather than our Bearer callback key. Send `X-Webhook-Signature: sha256=<hex>` and `X-Webhook-Timestamp: <epoch>`, where the HMAC-SHA256 is over \"{timestamp}.{raw body}\" with the shared secret. POST (JSON body) only. Our click id must be echoed under data.publisherParams.click_id; data.conversionId is the idempotency key. conversion.paid + data.paid=true books data.priceInUsd as revenue.",
                "operationId": "353e22db50bf19cc23d94c7a18f419a9",
                "responses": {
                    "200": {
                        "description": "Booked, recorded-as-rejected (unpaid), or an idempotent replay.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Body is not a JSON object.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid signature / stale timestamp.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Valid body but unbookable — missing/unknown click_id, click not owned by this partner, or a paid event with no price.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Transient write failure — retry.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/conversions": {
            "post": {
                "tags": [
                    "Conversions"
                ],
                "summary": "Post back a CPA job-application conversion",
                "description": "Sponsors call this when a click on their CPA job becomes an application. Authenticate with `Authorization: Bearer <callback key>` (your sponsor callback key, issued in the admin console — distinct from a publisher API key). ONE key covers every feed you run with us. Reference the click via the `click_id` we appended to your job URL on redirect. Idempotent: retrying the same (click_id, reference) returns the original conversion rather than double-booking. Revenue is computed from our recorded value, not any amount you send.",
                "operationId": "7240fd43aaffb72bf58acac2e678d1f6",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "click_id"
                                ],
                                "properties": {
                                    "click_id": {
                                        "description": "The opaque click id we appended to your job URL (via your configured click_id_param) on the outbound redirect.",
                                        "type": "string",
                                        "format": "uuid",
                                        "example": "a1b2c3d4-e5f6-1234-9abc-0123456789ab"
                                    },
                                    "reference": {
                                        "description": "Your own application/lead id. Optional but recommended — it is the idempotency key for retries. Omit it and we dedupe one conversion per click_id.",
                                        "type": "string",
                                        "example": "ZR-APP-99817",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Conversion recorded. `status` is `confirmed` when the click was billable, or `rejected` when it was not (a bot or duplicate click) — still stored for your dispute/audit trail.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "Idempotent replay — a conversion for this (click_id, reference) already existed; the original is returned and nothing was double-booked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Body is not a JSON object, or click_id is missing / malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, malformed, or unknown Bearer callback key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "click_id is unknown, or its provider does not belong to the authenticated sponsor.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Transient failure writing the conversion. Retry with backoff — the endpoint is idempotent.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "sponsorCallbackKey": []
                    }
                ]
            }
        },
        "/api/v1/feeds/{slug}": {
            "get": {
                "tags": [
                    "Feeds"
                ],
                "summary": "Download a publisher syndication feed file",
                "description": "Returns the caller's pre-generated, gzipped XML job feed as a file download (`Content-Type: application/gzip`, `Content-Disposition: attachment`). The feed is regenerated server-side on its own schedule; this endpoint serves the latest build. A publisher may only pull feeds owned by their own account. The bucket is private — bytes are proxied through the API, never a presigned/public S3 URL.\n\nAuthenticate with EITHER `Authorization: Bearer <api key>` OR a `?token=<api key>` query parameter — the same publisher key in both cases. This is the only endpoint that accepts the query-parameter form (for feed readers that can't set an Authorization header); the header takes precedence when both are supplied. NOTE: a key in the URL can be captured by intermediary/access logs, so prefer the header where you can, and use a dedicated, independently revocable key for URL pulls.\n\nThe header-less `?token=` path is additionally gated (a Bearer pull is not): the account must be allow-listed for header-less pulls (a key not allow-listed is rejected as 401, indistinguishable from a bad key), such pulls may optionally be restricted to a whitelist of source IPs (403 on a miss), and each feed may be pulled without a header only once per hour (429 with `Retry-After` when exceeded). Contact your account manager to be enabled for header-less pulls.",
                "operationId": "cc5692c9720bfd23f45f2c641898e1de",
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "description": "Feed slug (as configured for your account).",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "acme-nursing"
                    },
                    {
                        "name": "token",
                        "in": "query",
                        "description": "Publisher API key, as an alternative to the `Authorization: Bearer` header (header wins if both are sent). Header-less auth for feed readers that can't set headers. Prefer the header where possible — a URL-borne key can leak into access logs.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "example": "juju_pub_XXXXXXXXXXXXXXXXXXXXXXXX"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The gzipped XML feed file. Decompress to get `<jobs><job>…</job></jobs>`.",
                        "content": {
                            "application/gzip": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No valid credential — neither a `Authorization: Bearer <api key>` header nor a `?token=<api key>` query parameter resolved to an active key. As of 2026-09-03 api.publisher_auth_required is enabled, so an absent credential is a 401 rather than anonymous access. A `?token=` key whose account is not allow-listed for header-less pulls also 401s here, deliberately indistinguishable from an invalid key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Header-less (`?token=`) pull from a source IP that is not on this account's IP whitelist. Only applies to `?token=` pulls; use the `Authorization: Bearer` header, or pull from a whitelisted IP.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such feed for this account, the feed is inactive, or it has not been generated yet. (Ownership misses return 404, not 403, so a caller can't probe other publishers' slugs.)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Header-less (`?token=`) pull rate limit exceeded — a feed may be pulled once per hour (configurable per account) without an `Authorization` header. Includes a `Retry-After` header. Bearer-header pulls are not subject to this cap.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "The feed store is temporarily unreachable. Retry with backoff.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/jobs/search": {
            "get": {
                "tags": [
                    "Jobs"
                ],
                "summary": "Search active job postings",
                "description": "Paginated keyword + faceted search across all active job postings. Filters compose with AND semantics. Returns up to per_page Job documents per call. Filter values are escaped against Solr injection before query construction. Empty `q` matches everything (subject to the active campaign filter — only jobs with live sponsor budget are eligible). Results are DEDUPLICATED: the same job appearing across multiple feeds is collapsed to a single result (the highest-paying instance), so `total` and the rows reflect distinct jobs, not raw postings. NOTE: on API-key (publisher) responses the Job `id` is an opaque, stable token and `jobid` / `job_provider_id` are omitted (internal identifiers are not exposed); signed first-party responses carry the raw `id` + those fields.",
                "operationId": "57ac47a4e928a86c97e3ac597fb0490f",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Keyword. Escaped before Solr — special characters are safe.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "city",
                        "in": "query",
                        "description": "City to search near. By default this runs as a RADIUS around the city (api.default_radius_miles, >= 25 mi) — returning the surrounding metro, case-insensitively — not an exact city-name match. Pass an explicit `radius` to override.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "state",
                        "in": "query",
                        "description": "Exact-match state filter (full name or 2-letter code, depending on indexed data).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "postal",
                        "in": "query",
                        "description": "Postal code to search near. Like `city`, defaults to a radius search (api.default_radius_miles, >= 25 mi) unless an explicit `radius` is given.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "country",
                        "in": "query",
                        "description": "Exact-match country filter (e.g. `US`).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "remote",
                        "in": "query",
                        "description": "true|false. Filters by the is_remote field. Omit for no filter.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "description": "Category filter (exact match on indexed category).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "jobgroup",
                        "in": "query",
                        "description": "Job group filter (exact match).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "work_type",
                        "in": "query",
                        "description": "Work-type filter (exact match).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "jobgroupid",
                        "in": "query",
                        "description": "Numeric detailed O*NET occupation id (jobgroupid). Granular — prefer major_group_id for a category filter.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "major_group_id",
                        "in": "query",
                        "description": "O*NET major-group id (the 23-value taxonomy from /lookups `job_groups`). The canonical, controlled category filter — prefer this over the free-text `category`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "provider_id",
                        "in": "query",
                        "description": "Numeric job provider id. Scopes results to one sponsor.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "salary_min",
                        "in": "query",
                        "description": "Lower bound on salary_avg (inclusive).",
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "salary_max",
                        "in": "query",
                        "description": "Upper bound on salary_avg (inclusive).",
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "cpc_min",
                        "in": "query",
                        "description": "Lower bound on cpc.",
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "cpc_max",
                        "in": "query",
                        "description": "Upper bound on cpc.",
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "description": "Field + direction, e.g. `date_posted desc`. Allowed fields: date_posted, date_indexed, cpc, salary_avg. Anything else is silently ignored (relevance scoring is the default).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "posted_within",
                        "in": "query",
                        "description": "Recency filter (days). Only jobs posted within the last N days (clamped 1-365).",
                        "schema": {
                            "type": "integer",
                            "maximum": 365,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "radius",
                        "in": "query",
                        "description": "Radius (miles) around a resolved anchor named by `postal` OR (`city` + optionally `state`). OPTIONAL — a city/postal search already runs at the default radius (api.default_radius_miles, >= 25 mi); pass this to override it. When a radius is in effect, `city` / `postal` act as the anchor rather than exact-match filters. An unresolvable anchor falls back to an exact filter (search still runs).",
                        "schema": {
                            "type": "number",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "1-indexed page number (clamped to >= 1). Results past api.search_max_window — i.e. (page-1)*per_page at or beyond that window — are rejected with 400; page through the first N matches only. Use the syndication feed for bulk retrieval.",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "description": "Results per page. Clamped server-side to api.per_page_max (50).",
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "maximum": 50
                        }
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "description": "Response serialization. `json` (default) or `xml`. XML returns the SAME envelope with Content-Type `application/xml`: `<response><data><job>…</job></data><meta>…</meta><errors/></response>`. HTML-bearing fields (e.g. description) are CDATA-wrapped; facet-bucket values that are not valid XML tag names are emitted as `<entry key=\"…\">`. This XML option exists only on the public publisher endpoints (api.juju.com).",
                        "schema": {
                            "type": "string",
                            "default": "json",
                            "enum": [
                                "json",
                                "xml"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful search. `data` is an array of Job documents (possibly empty); `meta` carries pagination and facet rollups.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Job"
                                                    }
                                                },
                                                "meta": {
                                                    "required": [
                                                        "total",
                                                        "page",
                                                        "per_page",
                                                        "total_pages",
                                                        "facets"
                                                    ],
                                                    "properties": {
                                                        "total": {
                                                            "type": "integer",
                                                            "example": 64
                                                        },
                                                        "page": {
                                                            "type": "integer",
                                                            "example": 1
                                                        },
                                                        "per_page": {
                                                            "type": "integer",
                                                            "example": 10
                                                        },
                                                        "total_pages": {
                                                            "type": "integer",
                                                            "example": 7
                                                        },
                                                        "facets": {
                                                            "description": "Map of facet field → (map of value → count). Empty object if Solr returned no facet rollups for this query.",
                                                            "type": "object",
                                                            "example": {
                                                                "state": {
                                                                    "California": 17,
                                                                    "Idaho": 14
                                                                }
                                                            },
                                                            "additionalProperties": {
                                                                "type": "object",
                                                                "additionalProperties": {
                                                                    "type": "integer"
                                                                }
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Result window exceeded — the requested page is past api.search_max_window; the app rejects fetches beyond the first N matches to stop inventory scraping and expensive deep Solr offsets. Narrow the search with filters, or use the syndication feed for bulk pulls.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Credential missing or rejected. On api.juju.com (partner tier) a valid `Authorization: Bearer <key>` is REQUIRED as of 2026-09-03 — an absent header is a 401, not anonymous access. On webapi.juju.com (first-party tier) this instead means a missing or invalid HMAC signature.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Solr backend is temporarily unavailable. Retry with exponential backoff.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/jobs/{id}": {
            "get": {
                "tags": [
                    "Jobs"
                ],
                "summary": "Retrieve a single job by compound id",
                "description": "Returns a single Job document keyed by the raw compound id `{job_provider_id}_{jobid}`. This is the `id` that SIGNED first-party (webapi) search returns. API-key (publisher) search returns an OPAQUE, non-resolvable `id` instead, so publishers CANNOT use this endpoint — they consume search + `click_url`; detail-by-id is a first-party path only. No campaign-budget filter is applied — if a sponsor depletes their budget mid-session, jobs returned by an earlier search can still be looked up via this endpoint (the click-time matcher handles eligibility).",
                "operationId": "3b618931dad8aabd3e8b4342a461b53d",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Compound id `{job_provider_id}_{jobid}`.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "2_141096464"
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "description": "Response serialization: `json` (default) or `xml`. XML returns the same envelope with Content-Type application/xml; the single job is rendered as `<response><data>…fields…</data></response>`.",
                        "schema": {
                            "type": "string",
                            "default": "json",
                            "enum": [
                                "json",
                                "xml"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Single Job document in `data`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Job"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Missing id path parameter.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Credential missing or rejected. On api.juju.com (partner tier) a valid `Authorization: Bearer <key>` is REQUIRED as of 2026-09-03 — an absent header is a 401, not anonymous access. On webapi.juju.com (first-party tier) this instead means a missing or invalid HMAC signature.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No job with that id (expired, deleted, or never indexed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Solr backend is temporarily unavailable. Retry with backoff.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/jobs/count": {
            "get": {
                "tags": [
                    "Jobs",
                    "Monitoring"
                ],
                "summary": "Total indexed job count",
                "description": "Returns the raw count of job documents currently in the Solr index. Not filtered by campaign budget — represents inventory volume, not what would be served by /search. Useful for operator dashboards and \"are feeds importing?\" monitoring.",
                "operationId": "849b5861e211bc7d16fee5bd8c1f3738",
                "parameters": [
                    {
                        "name": "format",
                        "in": "query",
                        "description": "Response serialization: `json` (default) or `xml`. XML returns `<response><data>78335</data></response>` with Content-Type application/xml.",
                        "schema": {
                            "type": "string",
                            "default": "json",
                            "enum": [
                                "json",
                                "xml"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Raw integer in `data`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "integer",
                                                    "example": 78335
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Credential missing or rejected. On api.juju.com (partner tier) a valid `Authorization: Bearer <key>` is REQUIRED as of 2026-09-03 — an absent header is a 401, not anonymous access. On webapi.juju.com (first-party tier) this instead means a missing or invalid HMAC signature.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/jobs/budget-status": {
            "get": {
                "tags": [
                    "Jobs",
                    "Monitoring"
                ],
                "summary": "Campaign cache health probe",
                "description": "Reports whether the sponsor-budget cache that Jobs::search depends on is warm AND whether the refresh job is firing on schedule. Designed as a polling target for uptime monitors (Pingdom / CloudWatch synthetics / Datadog). Read-only, no business data leaks. AUTH CHANGED 2026-09-03: this endpoint carries api_auth, and api.publisher_auth_required is now enabled in production — so on api.juju.com a monitor MUST send `Authorization: Bearer <api key>` or it will receive 401 instead of the health body. Alert on stale_warning=true (refresh stopped firing — ~8min before customer impact) or live_providers=false (search already returning empty).",
                "operationId": "ae39f1257e3158496c202f530f990322",
                "responses": {
                    "200": {
                        "description": "Always 200. Read the body fields, not the status, to determine cache health.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "required": [
                                                        "live_providers",
                                                        "fq_clause",
                                                        "stale_warning",
                                                        "refresh_age_seconds",
                                                        "remaining_ttl_seconds"
                                                    ],
                                                    "properties": {
                                                        "live_providers": {
                                                            "description": "True iff campaign_live_providers key holds a non-empty array. False means /api/v1/jobs/search is currently returning empty results.",
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "fq_clause": {
                                                            "description": "True iff campaign_fq_clause key holds a non-empty string. Same effect on search as live_providers.",
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "stale_warning": {
                                                            "description": "True if the last successful refresh wrote longer than one tick (120s) ago. Fires before the cache expires; early signal that the refresh task has stopped.",
                                                            "type": "boolean",
                                                            "example": false
                                                        },
                                                        "refresh_age_seconds": {
                                                            "description": "Seconds since the most recent successful refresh wrote to the cache. Null if no refresh has been recorded (cache fully expired or first boot).",
                                                            "type": "integer",
                                                            "example": 45,
                                                            "nullable": true
                                                        },
                                                        "remaining_ttl_seconds": {
                                                            "description": "Seconds until the cache evicts if no further refresh occurs. Computed as CACHE_TTL (600) minus refresh_age.",
                                                            "type": "integer",
                                                            "example": 555
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Credential missing or rejected. As of 2026-09-03 a valid `Authorization: Bearer <key>` is REQUIRED on api.juju.com — an absent header is a 401, not anonymous access. Uptime monitors configured before that date will see this instead of the health body until a key is added to the probe.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/account": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Account - Get",
                "description": "Returns the logged-in publisher login's profile joined with their publisher org. Earnings numbers are NOT included — request /earnings for the summary or /reports/earnings for the daily breakdown.",
                "operationId": "fce02a2feda8c3afa6e9c23c0fbbee6e",
                "responses": {
                    "200": {
                        "description": "Current publisher account profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "username": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "phone": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "date_created": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "date_last_login": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        },
                                                        "publisher_id": {
                                                            "type": "integer"
                                                        },
                                                        "publisher_name": {
                                                            "type": "string"
                                                        },
                                                        "publisher_website": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "publisher_primary_contact": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "publisher_primary_email": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "publisher_primary_phone": {
                                                            "type": "string",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No valid session or the login is deactivated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/api-keys": {
            "get": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - List",
                "description": "Lists API-key accounts under the logged-in publisher. Returns prefix + last-4 hint + cpc_share + tier + date_created + date_last_used. NEVER returns plaintext or hash (we don't have the plaintext; we only stored the SHA-256 hash at issuance / regenerate time).",
                "operationId": "fc404538f24fe0cac2d5ad64a9183036",
                "responses": {
                    "200": {
                        "description": "Accounts list (unpaginated — small per publisher).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PublisherAccount"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/api-keys/{id}": {
            "patch": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Update Name",
                "description": "Rename an API-key account. Only `account_name` is mutable from this surface — cpc_share and rate_limit_tier are contract terms and must go through admin. Scope-checked: 404 for another org's account.",
                "operationId": "6d6e50999edb4d60e0b3510a5afce570",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "account_name": {
                                        "type": "string",
                                        "maxLength": 255
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherAccount"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found or not owned by this publisher.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/api-keys/{id}/regenerate": {
            "post": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Regenerate Key",
                "description": "Rotates key material IN PLACE on the same publisher_account row. The account (name, cpc_share, rate_limit_tier, historical click attribution) is preserved; only the key's prefix / hash / hint change. Old key stops authenticating IMMEDIATELY. Plaintext returned EXACTLY ONCE — unrecoverable after this response, same policy as admin issuance.",
                "operationId": "feaab4ad7bf5b533dfacc94b11df1d16",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Rotated. `data.api_key_plaintext` is returned exactly once.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/PublisherAccount"
                                                        },
                                                        {
                                                            "properties": {
                                                                "api_key_plaintext": {
                                                                    "description": "The full new plaintext key. Store immediately.",
                                                                    "type": "string"
                                                                },
                                                                "warning": {
                                                                    "type": "string"
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    ]
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found or not owned by this publisher.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Prefix collision on generation (pathologically rare).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/api-keys/{id}/revoke": {
            "post": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Revoke",
                "description": "Deactivates an API-key account (active=false). PublisherAuth denies the key on the next request — no cache warmup delay because the auth check is a per-request DB lookup. Historical click attribution keeps its FK to this row for billing continuity.",
                "operationId": "c23fbc5fa91a9bbbf67eb9df781eff4c",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PublisherAccount"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found or not owned by this publisher.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/api-keys/{id}/rotations": {
            "get": {
                "tags": [
                    "Publisher Account"
                ],
                "summary": "Publisher Account - Rotation History",
                "description": "Paginated audit log for this account — every rotate/revoke/reactivate/expire event, newest first. Scope-checked: publisher sees only their own accounts' history. `actor_display` is the human-readable name of whoever initiated each event (admin, one of the publisher's own logins, or \"system\").",
                "operationId": "38abc399212f7f2e99a8626356e2feb7",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 25,
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated rotation history for this account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PublisherKeyRotation"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Account not found or not owned by this publisher.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/auth/login": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Auth - Login",
                "description": "Body: {username, password}. Success mints a publisher-audience JWT (12h TTL default), sets it as an httpOnly + SameSite=Lax + Secure cookie, stamps date_last_login on the publisher_login row, and returns the publisher's public profile — including the linked publisher org id + name. Failures return 401 with a generic \"Invalid credentials.\" message — same response for unknown username and wrong password to avoid user enumeration.",
                "operationId": "15503a4abc8af48b645ea7c4fa236261",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "username",
                                    "password"
                                ],
                                "properties": {
                                    "username": {
                                        "type": "string",
                                        "example": "lisa.smith",
                                        "maxLength": 64
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "correct-horse-battery-staple"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Login succeeded. Session cookie set on response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "description": "publisher_login_id",
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "username": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "publisher_id": {
                                                            "description": "Publisher org — session scope for reports and account management.",
                                                            "type": "integer"
                                                        },
                                                        "publisher_name": {
                                                            "type": "string"
                                                        },
                                                        "date_last_login": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Wrong credentials.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate-limited (publisher `login` bucket).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/auth/logout": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Auth - Logout",
                "description": "Clears the session cookie. Stateless JWT — no server-side session row to destroy. Idempotent.",
                "operationId": "00dbc91b3ebaaf2f0eaf268b41244f91",
                "responses": {
                    "200": {
                        "description": "Cookie cleared (idempotent).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "logged_out": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/billing/payouts": {
            "get": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - My List",
                "operationId": "5d7853e79ee0edf7d4895bc07a5d448a",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "in_transit",
                                "paid",
                                "failed",
                                "returned",
                                "on_hold"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The publisher's payouts (drafts excluded).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Payout"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/billing/payouts/{id}": {
            "get": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - My Detail",
                "operationId": "906ed4c0075f93576c0665bb1f6ec86d",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Payout + line items.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Payout"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found / not yours.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/billing/balance": {
            "get": {
                "tags": [
                    "Payout"
                ],
                "summary": "Payout - My Balance",
                "description": "AP balance for the logged-in publisher — committed-but-unsettled payouts + adjustments (what we currently owe).",
                "operationId": "15ba8b8f452745f6824cd1583f65661e",
                "responses": {
                    "200": {
                        "description": "Balance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "balance": {
                                                            "type": "string"
                                                        },
                                                        "currency": {
                                                            "type": "string",
                                                            "example": "USD"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/earnings": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Earnings - Summary",
                "description": "Month-banded earnings summary for the logged-in publisher's org. Same shape as the admin publisher-detail's earnings_summary block. Use /reports/earnings for the daily breakdown behind these totals.",
                "operationId": "5eb34c1fd785747e402c739edf2e3902",
                "responses": {
                    "200": {
                        "description": "Earnings summary object.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/EarningsSummary"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/health": {
            "get": {
                "tags": [
                    "Health"
                ],
                "summary": "Publisher module liveness probe",
                "description": "Unauthenticated. Returns ok=true if the publisher module is loaded and the response pipeline is healthy. Wire into LB health checks. Does NOT exercise downstream dependencies.",
                "operationId": "4db78c34c5ea7acb0df2a1ed26bb18b3",
                "responses": {
                    "200": {
                        "description": "Module is up.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "required": [
                                                        "ok"
                                                    ],
                                                    "properties": {
                                                        "ok": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/reports/clicks": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Clicks",
                "description": "Daily click aggregates scoped to the logged-in publisher's org. Optional publisher_account_id narrows to one API-key account. Sourced from click_publisher_daily_rollup (refreshed every ~5 min). Group by date, account, publisher. The money column is net (share-adjusted) `earnings` — what the publisher keeps; the unshared gross is deliberately NOT exposed here.",
                "operationId": "36b7b053f57174bb60e548020e20f589",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "publisher_account_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. publisher_account_id accepts a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportPublisherClicksDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/reports/earnings": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Earnings",
                "description": "Daily share-adjusted earnings scoped to the logged-in publisher's org. Earnings read the snapshotted publisher_earnings on the rollup (share applied at roll time), so closed periods are immutable. Money as string DECIMAL. Group by date, account, publisher.",
                "operationId": "450f2ebf0943c58a282c7db697e54e9f",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "publisher_account_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. publisher_account_id accepts a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportPublisherEarningsDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/publisher/v1/reports/api-usage": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - API Usage",
                "description": "Daily publisher-API request aggregates scoped to the logged-in publisher's org. Optional publisher_account_id narrows to one API-key account. Query hits the monthly-partitioned api_request_log — wide ranges cross partition boundaries but stay indexed on created_at. Group by date, account, publisher.",
                "operationId": "15b08e4ffa8b312b0e20503ce7bb04dd",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "publisher_account_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. publisher_account_id accepts a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportApiUsageDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/account": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Account - Get",
                "description": "Returns the logged-in sponsor login's profile joined with their parent partner org and (when set) their sub-account provider. Same shape as the /sponsor/v1/auth/login response plus a bit more org context.",
                "operationId": "51a9491dd801bdeb5cda72fc7b2f8bd6",
                "responses": {
                    "200": {
                        "description": "Current sponsor account profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "username": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "phone": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "date_created": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "date_last_login": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        },
                                                        "job_partner_id": {
                                                            "type": "integer"
                                                        },
                                                        "job_partner_name": {
                                                            "type": "string"
                                                        },
                                                        "job_partner_website": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "job_partner_documentation": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "job_provider_id": {
                                                            "description": "Null when the login has org-wide access.",
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "job_provider_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "job_provider_feed_url": {
                                                            "type": "string",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No valid session or the login is deactivated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/auth/login": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Auth - Login",
                "description": "Body: {username, password}. Success mints a sponsor-audience JWT (12h TTL default), sets it as an httpOnly + SameSite=Lax + Secure cookie, stamps date_last_login on the sponsor_login row, and returns the sponsor's public profile — including the parent job_partner and optional job_provider sub-account scoping. Failures return 401 with a generic \"Invalid credentials.\" message — same response for unknown username and wrong password to avoid user enumeration.",
                "operationId": "02637b5cc21272332750d412712f145e",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "username",
                                    "password"
                                ],
                                "properties": {
                                    "username": {
                                        "type": "string",
                                        "example": "jane.doe",
                                        "maxLength": 64
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "correct-horse-battery-staple"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Login succeeded. Session cookie set on response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "description": "sponsor_login_id",
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "username": {
                                                            "type": "string"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "job_partner_id": {
                                                            "description": "Parent sponsor org — session scope for reports.",
                                                            "type": "integer"
                                                        },
                                                        "job_partner_name": {
                                                            "type": "string"
                                                        },
                                                        "job_provider_id": {
                                                            "description": "Optional sub-account scoping. Null = access across all providers under the partner.",
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "job_provider_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "date_last_login": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Wrong credentials.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate-limited (sponsor `login` bucket).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/auth/logout": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Auth - Logout",
                "description": "Clears the session cookie. Stateless JWT — no server-side session row to destroy; if the client presents the old cookie value on a subsequent request the SessionAuth filter rejects it once the JWT expiry passes. Idempotent — always returns 200.",
                "operationId": "70f783d1ae8c4c2e03dc3392b251f311",
                "responses": {
                    "200": {
                        "description": "Cookie cleared (idempotent).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "logged_out": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/billing/invoices": {
            "get": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - My List",
                "operationId": "2a5791808cabfacc1fd346966d2eaf72",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "open",
                                "paid",
                                "partially_paid",
                                "void",
                                "uncollectible"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The sponsor's invoices (drafts excluded).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Invoice"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/billing/invoices/{id}": {
            "get": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - My Detail",
                "operationId": "dd52c8a8d66c3491b83175094b2e7530",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Invoice + line items.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Invoice"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found / not yours.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/billing/balance": {
            "get": {
                "tags": [
                    "Invoice"
                ],
                "summary": "Invoice - My Balance",
                "description": "AR balance for the logged-in sponsor. Positive = owed; negative = on-account credit.",
                "operationId": "79ee97b051e85398cf88d8c99acf2994",
                "responses": {
                    "200": {
                        "description": "Balance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "balance": {
                                                            "type": "string",
                                                            "example": "4211.5500"
                                                        },
                                                        "currency": {
                                                            "type": "string",
                                                            "example": "USD"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/campaigns": {
            "get": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - List",
                "description": "Paginated list of campaigns owned by the logged-in sponsor. Scoped by resolve_scope() to the login's job_partner_id (+ optional sub-account job_provider_id filter for sub-account logins). Money as strings.",
                "operationId": "169a0a8e83c74546bbc94f762352d729",
                "parameters": [
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "paused",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 25,
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated campaign list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Campaign"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/campaigns/{id}/pause": {
            "post": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Pause",
                "description": "Pauses a campaign owned by the logged-in sponsor. Scope-checked — campaigns belonging to another org return 404 (not 403 — don't leak existence). Takes ~2 minutes to affect live search via the sponsor budget refresh cache.",
                "operationId": "27aafddae8a47c45d4e47841bd2c81fc",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paused.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Campaign"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Campaign not found or not owned by this sponsor.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/campaigns/{id}/resume": {
            "post": {
                "tags": [
                    "Campaign"
                ],
                "summary": "Campaign - Resume",
                "description": "Resumes a paused campaign owned by the logged-in sponsor. Scope-checked; same 2-minute cache propagation as pause.",
                "operationId": "f31ccc579120d2a4287589624ffde2e6",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resumed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Campaign"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Campaign not found or not owned by this sponsor.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/health": {
            "get": {
                "tags": [
                    "Health"
                ],
                "summary": "Sponsor module liveness probe",
                "description": "Unauthenticated. Returns ok=true if the sponsor module is loaded and the response pipeline is healthy. Wire into LB health checks. Does NOT exercise downstream dependencies.",
                "operationId": "8b7ef0e4a7860f835e2c2523e273f511",
                "responses": {
                    "200": {
                        "description": "Module is up.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "required": [
                                                        "ok"
                                                    ],
                                                    "properties": {
                                                        "ok": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/providers": {
            "get": {
                "tags": [
                    "Provider"
                ],
                "summary": "Provider - List",
                "description": "Read-only list of providers under the logged-in sponsor's org. Sub-account logins see only their one assigned provider. Same row shape as the admin providers list minus internal fields (schema_mapping, credential presence booleans, latest_run — those are ops-facing).",
                "operationId": "d90bef4773cd94aeb69a1744c8848803",
                "parameters": [
                    {
                        "name": "active",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "paused",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 25,
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated provider list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Provider"
                                                    }
                                                },
                                                "meta": {
                                                    "$ref": "#/components/schemas/PaginationMeta"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/reports/clicks": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Clicks",
                "description": "Daily click aggregates for the logged-in sponsor's own inventory, from the sponsor click rollup. Group by date, campaign, provider, segment. Always scoped to the sponsor's org (job_partner); sub-account logins (job_provider_id set on sponsor_login) are further scoped to that provider. Optional campaign_id narrows to one campaign. Does NOT expose publisher accounts or other sponsors' feeds — those dimensions do not exist on this report.",
                "operationId": "fe1dcfc64a05fd2e71079646e296d127",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "campaign_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. campaign_id accepts a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportSponsorClicksDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sponsor/v1/reports/spend": {
            "get": {
                "tags": [
                    "Report"
                ],
                "summary": "Reports - Spend",
                "description": "Daily spend aggregates scoped to the logged-in sponsor's org. Same scoping rules as clicks. Money returned as string DECIMAL — see the money-as-strings convention on the admin surface. Group by date, campaign, provider, segment.",
                "operationId": "80b4f1d17753950350b6af1c4823208e",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "campaign_id",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "group_by",
                        "in": "query",
                        "description": "Group-by dimensions (repeat or CSV). Allowed set is per report (see the reports changelog); default date. campaign_id accepts a single value or a CSV/repeat list.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "name": "bucket",
                        "in": "query",
                        "description": "Date bucket: day|week|month (default day).",
                        "schema": {
                            "type": "string",
                            "default": "day",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Daily rows, ordered by report_date DESC.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ReportSpendDailyRow"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "from/to missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/compliance/contact": {
            "post": {
                "tags": [
                    "Compliance"
                ],
                "summary": "Submit the contact form",
                "description": "Stores a contact-form submission. Public (no login). Returns `{status:\"received\"}` on success.",
                "operationId": "c20e4630bea130245dd23a0483217eab",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "first_name",
                                    "last_name",
                                    "email",
                                    "message"
                                ],
                                "properties": {
                                    "first_name": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "last_name": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "maxLength": 255
                                    },
                                    "phone": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 32
                                    },
                                    "message": {
                                        "type": "string",
                                        "maxLength": 5000
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Stored.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/compliance/privacy-request": {
            "post": {
                "tags": [
                    "Compliance"
                ],
                "summary": "Submit a state privacy request",
                "description": "Records a privacy request (store-only, admin-reviewed; no automatic action). Public (no login). One endpoint for all five `request_type` values; `options` are validated against the type. `message` is required only when `request_type=privacy_rights`. Returns `{status:\"received\"}`.",
                "operationId": "890a91ddf38133738560c5e29441a515",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "request_type",
                                    "first_name",
                                    "last_name",
                                    "email",
                                    "phone",
                                    "address1",
                                    "city",
                                    "state",
                                    "zip",
                                    "options"
                                ],
                                "properties": {
                                    "request_type": {
                                        "type": "string",
                                        "enum": [
                                            "do_not_sell_or_share",
                                            "privacy_rights",
                                            "opt_out_profiling",
                                            "opt_out_targeted_advertising",
                                            "limit_sensitive_information"
                                        ]
                                    },
                                    "first_name": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "last_name": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "maxLength": 255
                                    },
                                    "phone": {
                                        "type": "string",
                                        "maxLength": 32
                                    },
                                    "address1": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "address2": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "city": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "state": {
                                        "type": "string",
                                        "maxLength": 64
                                    },
                                    "zip": {
                                        "type": "string",
                                        "maxLength": 20
                                    },
                                    "options": {
                                        "description": "Valid values depend on request_type; see the guide.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "message": {
                                        "description": "Required only when request_type=privacy_rights.",
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 5000
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Request recorded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error (missing field, bad request_type, or options invalid for the type).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/compliance/unsubscribe": {
            "post": {
                "tags": [
                    "Compliance"
                ],
                "summary": "Request opt-out of email and/or SMS",
                "description": "At least one of `email` / `phone`. If a valid `token` (from the email link) is present AND `email` is unchanged from the token's address, the marketing opt-out is processed immediately and `status` is `\"unsubscribed\"`. Otherwise it's recorded for admin review and `status` is `\"received\"`. Public (no login).",
                "operationId": "f80f00a8995c1b84dce545789ea0dc0f",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "At least one of email / phone. `token` is the opaque value from the email link.",
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "phone": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 32
                                    },
                                    "token": {
                                        "description": "From the email unsubscribe link; enables the verified auto-process.",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`{status:\"unsubscribed\"}` (verified) or `{status:\"received\"}` (queued for review).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Neither email nor phone supplied, or an invalid email.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/compliance/unsubscribe/resolve": {
            "get": {
                "tags": [
                    "Compliance"
                ],
                "summary": "Resolve an unsubscribe token to its email (to pre-fill the page)",
                "description": "Given the `token` from an email unsubscribe link, returns the address it was issued to so the page can pre-fill it. Returns `{email:null}` for a missing/invalid token (page shows a blank form). Public (no login).",
                "operationId": "0ae30012300127c8891bc832432a1abb",
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`{email: <address>|null}`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/compliance/unsubscribe/one-click": {
            "post": {
                "tags": [
                    "Compliance"
                ],
                "summary": "RFC 8058 one-click unsubscribe",
                "description": "Target of the `List-Unsubscribe` header with `List-Unsubscribe-Post: List-Unsubscribe=One-Click`. A mail client POSTs here (no page, no body fields — `token` is in the query string) and the marketing opt-out is processed. PUBLIC + unauthenticated by design (mail providers cannot sign) — the token is the credential; rate-limited.",
                "operationId": "571f016d866370959fa5fca668ed68fd",
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Opt-out processed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Missing or invalid token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/lookups": {
            "get": {
                "tags": [
                    "Site"
                ],
                "summary": "Consumer search taxonomy (filter values)",
                "description": "The value sets for the SPA's search filters — categories (live Solr facet with counts), work types (canonical list), and curated locations — so filter dropdowns render without a search round-trip. Heavily cached. Every `key` round-trips to the matching /jobs/search filter param. Solr failure degrades categories to an empty array; the endpoint never 500s.",
                "operationId": "94fddd69282b6edce69ad847363cf9b9",
                "responses": {
                    "200": {
                        "description": "Consumer taxonomy payload.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "job_groups": {
                                                            "description": "Canonical O*NET major-group taxonomy (preferred category filter). key = major_group_id.",
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "key": {
                                                                        "description": "major_group_id — pass back as the `major_group_id` search param.",
                                                                        "type": "integer"
                                                                    },
                                                                    "label": {
                                                                        "type": "string"
                                                                    },
                                                                    "job_count": {
                                                                        "type": "integer"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        },
                                                        "categories": {
                                                            "description": "Legacy free-text provider categories (numeric ids filtered out). Prefer job_groups.",
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "key": {
                                                                        "description": "Pass back as the `category` search param.",
                                                                        "type": "string"
                                                                    },
                                                                    "label": {
                                                                        "type": "string"
                                                                    },
                                                                    "job_count": {
                                                                        "type": "integer"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        },
                                                        "work_types": {
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "key": {
                                                                        "description": "Pass back as the `work_type` search param.",
                                                                        "type": "string"
                                                                    },
                                                                    "label": {
                                                                        "type": "string"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        },
                                                        "locations": {
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "label": {
                                                                        "type": "string"
                                                                    },
                                                                    "city": {
                                                                        "type": "string"
                                                                    },
                                                                    "state_code": {
                                                                        "type": "string"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        },
                                                        "education_levels": {
                                                            "description": "Signup dropdown. Pass `id` back as register education_level_id.",
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "integer"
                                                                    },
                                                                    "label": {
                                                                        "type": "string"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        },
                                                        "future_education": {
                                                            "description": "Signup dropdown. Pass `id` back as register future_education_id.",
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "integer"
                                                                    },
                                                                    "label": {
                                                                        "type": "string"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/offers/next": {
            "get": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Serve (matcher)",
                "description": "Runs the serving-layer OfferMatcher for the current context and returns the single offer it would serve (highest tier, weighted-random within tier, hourly-floor aware), plus a match_id correlation token to thread through the funnel (pass it to /submit). Pass offer_list_id to serve from a specific list; omit it (and publisher_id) for native / search traffic, which draws from every active list. Context is built from an optional consumer session (age + zipcode from profile, lockout gating) and optional query params. Returns offer=null when nothing is eligible (a normal outcome, still 200). Does not pre-ping or log an impression.",
                "operationId": "1a3e1e5cd33a268ca813e471aad1c3be",
                "parameters": [
                    {
                        "name": "offer_list_id",
                        "in": "query",
                        "description": "The offer list to serve from. Optional — omit to draw from every list eligible for the context. When set, only that (active) list is considered.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "publisher_id",
                        "in": "query",
                        "description": "Publisher context. When set, narrows eligible lists to that publisher's assigned lists. Optional (omit for native / search traffic).",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sponsor_id",
                        "in": "query",
                        "description": "Adjacent job's sponsor. Reserved — not gated on today (future offer-level blocklist).",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "zipcode_id",
                        "in": "query",
                        "description": "Overrides the profile zipcode for the zipcode-allowlist gate.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "age",
                        "in": "query",
                        "description": "Overrides the profile-derived age for age gating.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The matched offer (or offer=null when none is eligible).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "offer": {
                                                            "oneOf": [
                                                                {
                                                                    "$ref": "#/components/schemas/OfferDisplay"
                                                                }
                                                            ],
                                                            "nullable": true
                                                        },
                                                        "match_id": {
                                                            "description": "Serve-correlation token; pass to /submit as match_id. Null when no offer.",
                                                            "type": "string",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/offers/{id}": {
            "get": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Display by id",
                "description": "Returns a single active offer's consumer-facing display fields by id — for a direct render when the caller already knows the offer (deep link, or a second render of a matched offer). No eligibility gating (schedule / zipcode / caps / lockout) is applied here, mirroring /jobs/{id}; the matcher endpoint is where eligibility is enforced. 404 if the offer is missing, inactive, or paused.",
                "operationId": "26efc78d34f0203aa2e8d61c084f5a93",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Offer display fields.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/OfferDisplay"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No active offer with that id.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/offers/{offer_id}/submit": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Submit",
                "description": "Consumer submits their answers to an offer. Server validates disqualifying_answers, conditionally pre-pings the partner (when offer.requires_preping = true), and writes offer_conversion on success. Pass offer_click_id (from /click) to link the funnel; for single-action forms use /click-submit instead.",
                "operationId": "81ee499abfc7c888984035a74348c1d5",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "answers"
                                ],
                                "properties": {
                                    "answers": {
                                        "description": "Keyed by offer.questions[].key. Values are the user's selections. Any answer matching that question's disqualifying_answers array rejects the submission.",
                                        "type": "object"
                                    },
                                    "source_solr_id": {
                                        "description": "Optional — the solr_id of the job displayed in context when the offer was surfaced/clicked. Attribution only; never required.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "match_id": {
                                        "description": "Optional serve-correlation token (from /offers/next).",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "offer_click_id": {
                                        "description": "Optional — the offer_click_id returned by /offers/{id}/click, linking this conversion back through click → impression.",
                                        "type": "integer",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Conversion accepted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "offer_conversion_id": {
                                                            "type": "integer"
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "example": "accepted"
                                                        },
                                                        "offer_preping_id": {
                                                            "description": "Present when pre-ping fired.",
                                                            "type": "integer",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found or not currently servable.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Consumer already converted on this offer within the lockout window.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Disqualifying answer, pre-ping decline, or unavailable partner.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/offers/{offer_id}/click-submit": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Click + Submit",
                "description": "One call for single-action offer forms: records the offer_click and then runs the full submission (disqualify check, conditional pre-ping, offer_conversion) against that click. The click persists even if the submission is disqualified or pre-ping-rejected (it is a real funnel event). Pass offer_impression_id to chain from an earlier impression. Same session + gating semantics as /submit; the response additionally returns offer_click_id.",
                "operationId": "7b65083df445ef955d679de64093b61b",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "answers"
                                ],
                                "properties": {
                                    "answers": {
                                        "description": "Keyed by offer.questions[].key. Disqualifying answers reject the submission.",
                                        "type": "object"
                                    },
                                    "offer_impression_id": {
                                        "description": "The impression that led to this click (from /impression).",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "source_solr_id": {
                                        "description": "Optional — solr_id of the job displayed in context. Attribution only.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "match_id": {
                                        "description": "Optional serve-correlation token (from /offers/next).",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Click recorded and conversion accepted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "offer_conversion_id": {
                                                            "type": "integer"
                                                        },
                                                        "offer_click_id": {
                                                            "description": "The click recorded for this action (null if the click write failed).",
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "example": "accepted"
                                                        },
                                                        "offer_preping_id": {
                                                            "type": "integer",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found or not currently servable.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Consumer already converted on this offer within the lockout window.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Disqualifying answer, pre-ping decline, or unavailable partner.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/offers/{offer_id}/click-through": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Click-through (redirect offer)",
                "description": "For REDIRECT offers (action_type=redirect): records the click, opens a PENDING conversion, builds the vendor tracking URL from the offer's redirect_template (substituting {click_id}=the new conversion id, {keyword}, {source}, and profile tokens from `lead`), and returns it as `redirect_url` for the SPA to open in a new tab. No answers, no disqualify check, no server-side delivery — the vendor confirms the conversion later via their postback (POST /api/v1/offers/postback/{partner}), which flips the row to delivered and records the reported revenue. Same session + lockout semantics as /submit. The exact substituted URL is retained on the lead snapshot as the \"what we posted\" audit record, then time-scrubbed per offer.outbound_url_retention_days.",
                "operationId": "fe227b5b5d715ba2695e5b0beeb1223d",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "keyword": {
                                        "description": "User's job-search keyword → sub2 in the outbound URL.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "source": {
                                        "description": "Traffic-source / page id → sub1. Optional; blank is fine.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "lead": {
                                        "description": "Profile fields for URL prefill (first_name, last_name, email, phone, zip, city, state, address, gender, dob). Also snapshotted for compliance.",
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "offer_impression_id": {
                                        "description": "The impression that led to this click.",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "source_solr_id": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "match_id": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Click recorded, pending conversion opened, redirect URL returned.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "redirect_url": {
                                                            "description": "Open in a new tab (offer action.target=_blank).",
                                                            "type": "string"
                                                        },
                                                        "offer_conversion_id": {
                                                            "type": "integer"
                                                        },
                                                        "offer_click_id": {
                                                            "type": "integer",
                                                            "nullable": true
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "example": "accepted"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Offer not found or not currently servable.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Consumer already responded within the lockout window.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Offer is not a redirect offer.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Redirect offer is misconfigured (no redirect_template).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/offers/{offer_id}/impression": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Record Impression",
                "description": "Called by the SPA when an offer clears its viewport / render threshold. Records one offer.offer_impression row and returns its id so the SPA can thread it into the subsequent click call. HMAC-only + session-optional; best-effort (always 200 unless the body is malformed).",
                "operationId": "2ad9f3b6dfe5b13c55f7e332ac80e6f7",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "display_context"
                                ],
                                "properties": {
                                    "display_context": {
                                        "description": "Where/how the offer rendered. Unknown values coerce to \"other\".",
                                        "type": "string",
                                        "enum": [
                                            "modal_solo",
                                            "modal_list",
                                            "sidebar",
                                            "inline_list",
                                            "banner",
                                            "interstitial",
                                            "footer",
                                            "other"
                                        ]
                                    },
                                    "page_url": {
                                        "description": "URL the offer appeared on. May carry search terms — treated as PII-adjacent.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "position": {
                                        "description": "Position within the container (1..N).",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "offer_preping_id": {
                                        "description": "Set only if a display-time pre-ping already ran for this render.",
                                        "type": "integer",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Impression recorded (or silently skipped).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "recorded": {
                                                            "type": "boolean"
                                                        },
                                                        "offer_impression_id": {
                                                            "description": "Pass to the click call to link the funnel.",
                                                            "type": "integer",
                                                            "format": "int64",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "display_context missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/offers/{offer_id}/click": {
            "post": {
                "tags": [
                    "Offer"
                ],
                "summary": "Offer - Record Click",
                "description": "Called by the SPA when the user interacts with an offer's CTA. Records one offer.offer_click row and returns its id for threading into /submit. HMAC-only + session-optional; best-effort (always 200 unless the body is malformed).",
                "operationId": "59e2460bfbf74a4a8acd90e7ed8ef57a",
                "parameters": [
                    {
                        "name": "offer_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "offer_impression_id": {
                                        "description": "The impression that led to this click (from the impression call).",
                                        "type": "integer",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Click recorded (or silently skipped).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "recorded": {
                                                            "type": "boolean"
                                                        },
                                                        "offer_click_id": {
                                                            "description": "Pass to /submit as offer_click_id to link the funnel.",
                                                            "type": "integer",
                                                            "format": "int64",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/site/home": {
            "get": {
                "tags": [
                    "Site"
                ],
                "summary": "Homepage aggregate — stats, facets, curated content",
                "description": "Single call that populates every content block on the consumer homepage. Heavily cached (default 15 min) so a homepage SSR render is one request. Blocks: stats (Solr document count + marketing values), popular_searches (curated), trending_searches (curated fallback), categories (top N Solr facet on `category`), top_companies (curated pending Solr schema addition), locations (curated). Solr failures degrade to zero counts / curated fallbacks — endpoint never 500s.",
                "operationId": "a1d434409a9d9e112ba6924f6b9cfe00",
                "responses": {
                    "200": {
                        "description": "Homepage aggregate payload.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "stats": {
                                                            "properties": {
                                                                "total_jobs": {
                                                                    "type": "integer",
                                                                    "example": 2241847
                                                                },
                                                                "jobs_updated_today": {
                                                                    "type": "integer",
                                                                    "example": 2241847
                                                                },
                                                                "partner_sites": {
                                                                    "type": "integer",
                                                                    "example": 50000
                                                                },
                                                                "update_interval_minutes": {
                                                                    "type": "integer",
                                                                    "example": 15
                                                                }
                                                            },
                                                            "type": "object"
                                                        },
                                                        "popular_searches": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            }
                                                        },
                                                        "trending_searches": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            }
                                                        },
                                                        "job_groups": {
                                                            "description": "Canonical O*NET major-group taxonomy (preferred category filter). key = major_group_id.",
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "key": {
                                                                        "description": "major_group_id — pass back as the `major_group_id` search param.",
                                                                        "type": "integer"
                                                                    },
                                                                    "label": {
                                                                        "type": "string"
                                                                    },
                                                                    "job_count": {
                                                                        "type": "integer"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        },
                                                        "top_companies": {
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "name": {
                                                                        "type": "string"
                                                                    },
                                                                    "job_count": {
                                                                        "description": "Null on curated rows; a real count once the Solr `company_str` field lands.",
                                                                        "type": "integer",
                                                                        "nullable": true
                                                                    },
                                                                    "logo": {
                                                                        "type": "string",
                                                                        "nullable": true
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        },
                                                        "locations": {
                                                            "type": "array",
                                                            "items": {
                                                                "properties": {
                                                                    "label": {
                                                                        "type": "string"
                                                                    },
                                                                    "city": {
                                                                        "type": "string"
                                                                    },
                                                                    "state_code": {
                                                                        "type": "string"
                                                                    }
                                                                },
                                                                "type": "object"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/site/landing": {
            "get": {
                "tags": [
                    "Site"
                ],
                "summary": "SEO landing aggregate for a category/location slice",
                "description": "Aggregate for a browse/SEO landing page — \"N jobs in {slice}\" plus a teaser list and related-refinement links. Accepts the same filter params as /jobs/search (q, category, jobgroup, work_type, city, state, postal, country, remote) and returns the count, a small sample of Job cards (link them to /jobs/{id} — the full apply flow lives on the detail page), and related category/location/work-type facets for internal linking. Inventory matches /jobs/search exactly (same live-budget gate). Short-cached; the FE owns the pretty-URL → param mapping.",
                "operationId": "6a0cc340cb3c1c6208965c5935c82822",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "jobgroup",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "work_type",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "city",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "state",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "postal",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "country",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "remote",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Landing aggregate. Never 500s from Solr issues — degrades to zero-count.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "filters": {
                                                            "description": "Echoed resolved filters (only the params that were provided).",
                                                            "type": "object"
                                                        },
                                                        "total_jobs": {
                                                            "type": "integer",
                                                            "example": 1234
                                                        },
                                                        "sample_jobs": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/Job"
                                                            }
                                                        },
                                                        "related": {
                                                            "properties": {
                                                                "categories": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "properties": {
                                                                            "key": {
                                                                                "type": "string"
                                                                            },
                                                                            "label": {
                                                                                "type": "string"
                                                                            },
                                                                            "job_count": {
                                                                                "type": "integer"
                                                                            }
                                                                        },
                                                                        "type": "object"
                                                                    }
                                                                },
                                                                "locations": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "properties": {
                                                                            "key": {
                                                                                "type": "string"
                                                                            },
                                                                            "label": {
                                                                                "type": "string"
                                                                            },
                                                                            "job_count": {
                                                                                "type": "integer"
                                                                            }
                                                                        },
                                                                        "type": "object"
                                                                    }
                                                                },
                                                                "work_types": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "properties": {
                                                                            "key": {
                                                                                "type": "string"
                                                                            },
                                                                            "label": {
                                                                                "type": "string"
                                                                            },
                                                                            "job_count": {
                                                                                "type": "integer"
                                                                            }
                                                                        },
                                                                        "type": "object"
                                                                    }
                                                                }
                                                            },
                                                            "type": "object"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/tracking/session": {
            "post": {
                "tags": [
                    "Tracking"
                ],
                "summary": "Tracking - Start Session",
                "description": "Called by the SPA on FIRST page load per visit. Records a site_session row with landing + attribution + parsed device + geo, upserts the site_visitor row by cookie token, and sets two httpOnly cookies on the response so subsequent /page-view calls work without the SPA managing tokens explicitly.\n\nIdempotent-ish: a repeat call within the same visit generates a NEW site_session (that's the definition of \"new visit\"), reusing the visitor cookie if present.\n\n─── Cookies set on response ────────────────────────────\n  juju_tracking_visitor  httpOnly, 1-year, SameSite=Lax\n  juju_tracking_session  httpOnly, session, SameSite=Lax\n\n─── Failure semantics ──────────────────────────────────\nAlways 200 unless the request itself is unparseable. Tracking is best-effort; page rendering must never be gated on this endpoint.",
                "operationId": "69a66a142c15d60dff1ff949c54054d0",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "landing_path": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 500
                                    },
                                    "landing_query": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "referrer": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "utm_source": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "utm_medium": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "utm_campaign": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "utm_term": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "utm_content": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "gclid": {
                                        "description": "Google Ads click id",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "fbclid": {
                                        "description": "Meta click id",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "msclkid": {
                                        "description": "Microsoft Ads click id",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Session recorded (or silently skipped). Cookies set on response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "recorded": {
                                                            "description": "False on DB failure; SPA should proceed regardless.",
                                                            "type": "boolean"
                                                        },
                                                        "is_new_visitor": {
                                                            "type": "boolean"
                                                        },
                                                        "is_bot": {
                                                            "description": "The recorded UA classified as a bot. Advisory only.",
                                                            "type": "boolean"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/tracking/page-view": {
            "post": {
                "tags": [
                    "Tracking"
                ],
                "summary": "Tracking - Record Page View",
                "description": "Called by the SPA on EVERY navigation. Reads session_token from the juju_tracking_session cookie set by /tracking/session, writes one juju.page_tracking row, increments the session's page_count.\n\n─── prev_duration_ms — the exit-beacon substitute ─────────\nWhen the SPA records page N+1 it reports how long the user spent on page N via prev_duration_ms. That avoids the beforeunload beacon (unreliable, doubles the request volume). The last page of each session is unmeasured — acceptable.\n\n─── page_type + entity_id ─────────────────────────────────\npage_type is a stable enum-ish string the SPA sends explicitly (home|search|job_detail|register|offer|saved-jobs|profile|...). entity_id is what the page is ABOUT (solr_id for a job page, category slug for a category page, offer_id for an offer). Together they make funnel + engagement queries trivial without regex-parsing url_path.\n\nBots: the endpoint silently 200-with-recorded=false when the session is bot-flagged and tracking.store_bot_page_views is false (default). No 4xx — bots would fill the SPA console with errors we don't want.",
                "operationId": "e57b531244078018761828da9eec267a",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "url_path"
                                ],
                                "properties": {
                                    "url_path": {
                                        "type": "string",
                                        "maxLength": 500
                                    },
                                    "query_string": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "page_type": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 32
                                    },
                                    "entity_id": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "prev_duration_ms": {
                                        "description": "Milliseconds spent on the PREVIOUS page. Omitted on the first page of a session.",
                                        "type": "integer",
                                        "nullable": true,
                                        "minimum": 0
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Page view recorded, or silently skipped (bot session / missing session cookie / DB failure). SPA MUST proceed regardless.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "recorded": {
                                                            "type": "boolean"
                                                        },
                                                        "sequence": {
                                                            "description": "Which page-in-session this write occupied (1 = first).",
                                                            "type": "integer",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "url_path missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/tracking/impression": {
            "post": {
                "tags": [
                    "Tracking"
                ],
                "summary": "Tracking - Record Impression",
                "description": "Called by the SPA when a job card CLEARS THE VIEWPORT THRESHOLD (IAB standard: 50% pixels visible for ≥1s). Distinct from /tracking/page-view — one impression per JOB seen on a page.\n\n─── The click_token is the identifier ────────────────────\nSend the exact token from the job's `click_url` field (the string after `/jobs/click/`). The server decodes it to recover solr_id, publisher_account_id, and served_id in one step — the SPA does not need to plumb those separately.\n\n─── Response ─────────────────────────────────────────────\nReturns `impression_id` when the row was written. Attach it as `?imp={impression_id}` on the click_url when rendering the <a href>, e.g.:\n\n  `<a href=\"{click_url}?imp={impression_id}\">Apply</a>`\n\nA click that lands on the server WITH the ?imp parameter will attribute back to this specific impression row, closing the served → impression → click chain.\n\n─── Failure semantics ────────────────────────────────────\nAlways 200 unless the request body is malformed. `recorded: false` means the token was bad, referred to a served row we no longer have, or the write failed — SPA should proceed with an un-attributed click URL. Never gate rendering on this endpoint.",
                "operationId": "06f7761fd2e0961d140233459535ab58",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "click_token"
                                ],
                                "properties": {
                                    "click_token": {
                                        "description": "The opaque token from the job's `click_url`.",
                                        "type": "string"
                                    },
                                    "viewport_duration_ms": {
                                        "description": "How long the card was in the viewport before this call. Optional.",
                                        "type": "integer",
                                        "nullable": true,
                                        "minimum": 0
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Impression recorded (or silently skipped on bad token / missing served row / DB failure).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "recorded": {
                                                            "type": "boolean"
                                                        },
                                                        "impression_id": {
                                                            "description": "Attach as `?imp=` on the click URL to close the attribution chain.",
                                                            "type": "integer",
                                                            "format": "int64",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "click_token missing or empty.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/tracking/list-impression": {
            "post": {
                "tags": [
                    "Tracking"
                ],
                "summary": "Tracking - Record List Impression",
                "description": "Called by the SPA when job TITLE(S) in the scrollable results list clear the viewport — the left-rail list, NOT the expanded full job display. Distinct from /tracking/impression (which is the full display, one job with all fields + the apply button). Keeping the two surfaces in separate tables makes the funnel legible: served → list-seen → full-viewed → clicked.\n\n─── Batch shape ──────────────────────────────────────────\nA list scroll surfaces many titles, so this endpoint is batch-first: send `click_tokens` — an array of the exact tokens from each list item's `click_url` (the string after `/jobs/click/`). A single `click_token` is also accepted. Duplicate tokens within one call are collapsed (a title scrolling in/out shouldn't double-count); at most 100 tokens are processed per call (excess dropped). Fire once per title per search to keep the list-seen ratio meaningful.\n\n─── Failure semantics ────────────────────────────────────\nAlways 200 unless the body carries no usable token. `recorded` is how many rows were written (tokens that were bad, referred to a served row we no longer have, or failed to write are simply not counted). Never gate rendering on this endpoint.",
                "operationId": "297a3e8753fdb14729c66be957b8bb93",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "click_tokens": {
                                        "description": "Preferred. The click_url tokens of the list items that cleared the viewport.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "click_token": {
                                        "description": "Single-item convenience form; use click_tokens for a list.",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "List impressions recorded (or silently skipped per token).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "recorded": {
                                                            "description": "How many list_impression rows were written.",
                                                            "type": "integer"
                                                        },
                                                        "total": {
                                                            "description": "How many distinct tokens were processed (after de-dupe + cap).",
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "No usable click_tokens / click_token in the body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/register": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Create a new consumer account (passwordless)",
                "description": "Passwordless signup. Accepts email (required) + optional name / phone plus the signup-form fields (education_level_id, future_education_id, gig_work_interest) and a REQUIRED terms_of_service consent. No password is collected: the account is created without one, the caller is logged in immediately (session cookie set on the response), and a magic-link \"set your password\" token is issued. Email delivery of that link is pending SES; until then the token is logged and — outside production only — returned as set_password_token so the flow is testable. Email + phone resolve to shared identity-artifact rows; phone is E.164-normalized. Terms consent is recorded (append-only) against the active terms_of_service document with the request IP hash + user agent. An optional trusted_form_url (TrustedForm consent certificate captured on the signup page) is stored as a consent_certificate row and linked to that consent event.",
                "operationId": "e4c3efd1916ed8d6356cf8e9a9fdfe4d",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email",
                                    "terms_consented"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "jed@example.com",
                                        "maxLength": 255
                                    },
                                    "first_name": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "last_name": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "phone": {
                                        "description": "Any format; server normalizes to E.164.",
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 30
                                    },
                                    "education_level_id": {
                                        "description": "FK to juju.education_level (options via GET /lookups).",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "future_education_id": {
                                        "description": "FK to juju.future_education (options via GET /lookups).",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "gig_work_interest": {
                                        "type": "boolean",
                                        "nullable": true
                                    },
                                    "trusted_form_url": {
                                        "description": "TrustedForm consent-certificate URL captured on the signup page. Stored against the user (juju.consent_certificate) as proof of TCPA consent and linked to the terms consent event.",
                                        "type": "string",
                                        "format": "uri",
                                        "nullable": true,
                                        "maxLength": 500
                                    },
                                    "terms_consented": {
                                        "description": "Must be true — the user accepted the Terms of Service.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Account created and logged in. Session cookie set on the response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64",
                                                            "example": 1234
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "example": "jed@example.com"
                                                        },
                                                        "logged_in": {
                                                            "type": "boolean",
                                                            "example": true
                                                        },
                                                        "verification_sent": {
                                                            "description": "False until email infrastructure (SES) lands.",
                                                            "type": "boolean",
                                                            "example": false
                                                        },
                                                        "set_password_token": {
                                                            "description": "DEV ONLY (non-production): the magic-link token, so the set-password flow is testable before SES. Never present in production.",
                                                            "type": "string",
                                                            "nullable": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "An active account with this email already exists.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure: email malformed, phone unparseable, unknown lookup id, or terms not accepted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/set-password": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Set a password via magic-link token",
                "description": "Consumes a single-use set_password token (from the magic-link email issued at signup) and sets the account password. On success the session cookie is set, so the browser that opened the link is logged in. The token is single-use and expiring; a used / expired / unknown token 400s. Because the token was delivered by email, a successful consume also marks the email verified (stamps juju.email.date_verified).",
                "operationId": "0cc2f8436daf93948344fd503216b9d9",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token",
                                    "password"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "The set_password token from the magic link.",
                                        "type": "string"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "correct-horse-battery-staple",
                                        "minLength": 12
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Password set; session cookie issued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "logged_in": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Token invalid, expired, or already used.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Password too short / missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/reset-password": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Set a new password via a password-reset token",
                "description": "Consumes a single-use password_reset token (from the reset email) and sets a new account password. On success the session cookie is issued, logging the browser in. Single-use + expiring; a used / expired / unknown token 400s. Identical mechanics to set-password; the two differ only in which token purpose they accept. Because the token was delivered by email, a successful consume also marks the email verified (stamps juju.email.date_verified).",
                "operationId": "4eb43880a7a2cc08e14508ae4c0bc9e9",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token",
                                    "password"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "The password_reset token from the reset link.",
                                        "type": "string"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "correct-horse-battery-staple",
                                        "minLength": 12
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Password set; session cookie issued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Token invalid, expired, or already used.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Password too short / missing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/request-password-reset": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Request a password-reset email",
                "description": "Issues a single-use password_reset token and emails the reset link (queued via mail_queue). ALWAYS returns 200 with the same generic message whether or not an account exists for the address — this is deliberate, to prevent account enumeration.",
                "operationId": "8380ceb67016b802d922429ff9fdd1b3",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "jed@example.com"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Generic acknowledgement (sent if the account exists).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Email missing / malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/send-verification": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Send (or resend) the email-verification link",
                "description": "For the authenticated consumer, issues a single-use email_verify token and queues the verification email to their address. No-op (still 200) if the email is already verified. Requires the session cookie.",
                "operationId": "5f07ae1aac95887e55f03fc1d48c650c",
                "responses": {
                    "200": {
                        "description": "Verification email queued (or already verified).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No valid session.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/verify-email": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Verify an email address via token",
                "description": "Consumes a single-use email_verify token and stamps date_verified on the email artifact (juju.email). Session-less — the token is the proof. A used / expired / unknown token 400s.",
                "operationId": "b95d8ea17e8f1e050a5e7b78a877ebf0",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "The email_verify token from the link.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Email verified.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Token invalid, expired, or already used.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/terms": {
            "get": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Fetch the active Terms of Service document",
                "description": "Returns the current active terms_of_service consent document so the SPA can render it before the signup consent checkbox. Anonymous — no session required. body_html holds the disclosure as stored (plain text or HTML). 404 if no active terms document is published.",
                "operationId": "484fd2d486c750c14485061b4c11e648",
                "responses": {
                    "200": {
                        "description": "Active terms document.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "consent_document_id": {
                                                            "type": "integer"
                                                        },
                                                        "consent_type": {
                                                            "type": "string",
                                                            "example": "terms_of_service"
                                                        },
                                                        "version": {
                                                            "type": "string",
                                                            "example": "1.0-placeholder"
                                                        },
                                                        "body_html": {
                                                            "type": "string"
                                                        },
                                                        "date_created": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No active terms document published.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/login": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Authenticate and issue a session cookie",
                "description": "Accepts email + password. On success, mints a session JWT and sets it as an httpOnly + SameSite=Lax cookie. Returns the user profile. Login does NOT require verified email (soft-lock). Suppressed emails (hard-bounced / complained / manually blocked) are rejected with the same generic 401 as wrong credentials — no enumeration signal. Failures use a generic \"Invalid credentials\" message regardless of whether the email exists or the password was wrong.",
                "operationId": "46771a5de53ffbb58403e859b03a80e5",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email",
                                    "password"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "jed@example.com"
                                    },
                                    "password": {
                                        "type": "string",
                                        "example": "correct-horse-battery-staple"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Login succeeded. Session cookie set on the response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "date_verified": {
                                                            "description": "Null = email not yet verified. Lives on the email artifact, not the user.",
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        },
                                                        "mfa_method": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "enum": [
                                                                "totp",
                                                                "email"
                                                            ]
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Wrong credentials. Same response for \"email not found\", \"wrong password\", and \"suppressed email\".",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/auth/logout": {
            "post": {
                "tags": [
                    "Users",
                    "Auth"
                ],
                "summary": "Clear the consumer session cookie",
                "description": "Sets the session cookie to empty with immediate expiry. No DB write — stateless JWTs don't have a server-side \"session row\" to destroy. Always returns 200 — idempotent.",
                "operationId": "2e04efae9c823f6de35715f375e53f57",
                "responses": {
                    "200": {
                        "description": "Cookie cleared (idempotent).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "logged_out": {
                                                            "type": "boolean",
                                                            "example": true
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/profile": {
            "get": {
                "tags": [
                    "Users",
                    "Profile"
                ],
                "summary": "Fetch the logged-in consumer's profile",
                "description": "Returns the profile fields for the consumer identified by the session cookie. Joins juju.email + juju.phone for display fields. Omits sensitive fields (password_hash, MFA secrets). user_id comes from the session, NOT the URL, so a consumer can never read another consumer's profile via this endpoint.",
                "operationId": "7d719057beb6aa581e69fd2dec672101",
                "responses": {
                    "200": {
                        "description": "Current profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/JsonEnvelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "properties": {
                                                        "user_id": {
                                                            "type": "integer",
                                                            "format": "int64"
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email"
                                                        },
                                                        "first_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "last_name": {
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "phone": {
                                                            "description": "E.164-normalized.",
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "country": {
                                                            "description": "ISO 3166-1 alpha-2.",
                                                            "type": "string",
                                                            "nullable": true
                                                        },
                                                        "date_created": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "date_verified": {
                                                            "description": "When the email artifact was verified — lives on juju.email, not the user.",
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        },
                                                        "date_last_login": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true
                                                        },
                                                        "mfa_method": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "enum": [
                                                                "totp",
                                                                "email"
                                                            ]
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No valid session cookie, OR the session's user_id no longer corresponds to an active account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Users",
                    "Profile"
                ],
                "summary": "Update mutable profile fields",
                "description": "Accepts first_name, last_name, phone, country. Email changes go through a separate verification flow. Password and MFA settings go through dedicated flows. Phone is E.164-normalized via libphonenumber and resolves to a juju.phone artifact row (reusing the existing one if the number already exists). Unknown fields in the request body are silently ignored. Empty PATCH body returns the current profile unchanged.",
                "operationId": "60393c2d6f577709776dff6349844400",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "first_name": {
                                        "description": "Set to null or empty string to clear.",
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "last_name": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "phone": {
                                        "description": "Any format; server normalizes to E.164. Null clears.",
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 30
                                    },
                                    "country": {
                                        "description": "ISO 3166-1 alpha-2 ('US', 'CA', 'GB'). Null clears.",
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 2
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated profile (or unchanged profile if PATCH had no mutable fields).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No valid session cookie.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure (e.g., unparseable phone, country not 2 chars).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/saved-jobs": {
            "get": {
                "tags": [
                    "Users",
                    "SavedJobs"
                ],
                "summary": "List the logged-in consumer's saved jobs",
                "description": "Paginated. Each item includes the cached display fields (title, company, city/state/postal/country) captured at save time plus user state (date_saved, date_applied, notes). The `active` field flags whether the underlying job is still live in Solr — currently always `null` (Solr merge is future work); the SPA can render an \"expired\" badge once `active === false` starts appearing.",
                "operationId": "d373d5f7a7a6acd168c4a6b24950a52e",
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "maximum": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated saved-job list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Users",
                    "SavedJobs"
                ],
                "summary": "Save a job to the user's watchlist",
                "description": "Body `{solr_id, job_title?, job_company?, job_city?, job_state?, job_postal?, job_country?, notes?}`. Idempotent on `(user_id, solr_id)` — re-saving the same job returns 200 with the existing row (not 409). Display fields are optional but STRONGLY encouraged — they're what the list surfaces after the job expires from Solr.",
                "operationId": "646bb7bcb5b9457fa52e83ca26fa5066",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "solr_id"
                                ],
                                "properties": {
                                    "solr_id": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "job_title": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "job_company": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 255
                                    },
                                    "job_city": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "job_state": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "job_postal": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 20
                                    },
                                    "job_country": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 50
                                    },
                                    "notes": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 5000
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Newly saved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "Already saved; existing row returned.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/saved-jobs/ids": {
            "get": {
                "tags": [
                    "Users",
                    "SavedJobs"
                ],
                "summary": "Unpaginated list of the user's saved (saved_job_id, solr_id) pairs",
                "description": "Cheap two-column query used by the SPA to render bookmark-toggle state on search results without fetching the full paginated list. Capped at 1000 items (well above any realistic saved-list size); if a caller hits the cap they get the 1000 most-recent — practical edge case, not a hard limit on the underlying data.",
                "operationId": "f2e7b32c3e63019a5bcf745031d50e51",
                "responses": {
                    "200": {
                        "description": "Array of {saved_job_id, solr_id}.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/saved-jobs/{saved_job_id}": {
            "delete": {
                "tags": [
                    "Users",
                    "SavedJobs"
                ],
                "summary": "Remove a saved job",
                "description": "Idempotent — returns 200 whether the row existed or not. Ownership enforced by user_id scoping; a saved_job_id owned by another user is treated as \"already deleted\" (silent 200).",
                "operationId": "665361706cfa92a174f09a67772b6ec8",
                "parameters": [
                    {
                        "name": "saved_job_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed (idempotent).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Users",
                    "SavedJobs"
                ],
                "summary": "Update notes and/or applied-at on a saved job",
                "description": "Body accepts `notes` (string or null) and/or `date_applied` (ISO-8601 timestamp or null). \"Mark as applied\" = set date_applied to the current timestamp; \"unmark\" = set to null. Empty PATCH is a no-op that returns the current row. Ownership enforced by user_id scoping — attempting to PATCH another user's row returns 404.",
                "operationId": "73fa094963e100aaa0691b4144d48463",
                "parameters": [
                    {
                        "name": "saved_job_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "notes": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 5000
                                    },
                                    "date_applied": {
                                        "type": "string",
                                        "format": "date-time",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated row.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Saved job not found or not owned by caller.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/saved-jobs/export": {
            "get": {
                "tags": [
                    "Users",
                    "SavedJobs"
                ],
                "summary": "Export the user's saved jobs as CSV",
                "description": "Returns text/csv (NOT the JSON envelope) so the browser downloads it as a file. All saved jobs, all fields — useful for users who need historical records before the retention purge (3y unapplied / 7y applied) removes them. Streams via setBody(); large lists still fit in one response since each user is naturally bounded.",
                "operationId": "46c0a13124e2c6a46e611cbd7d8217b8",
                "responses": {
                    "200": {
                        "description": "CSV download.",
                        "content": {
                            "text/csv": {}
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/saved-searches": {
            "get": {
                "tags": [
                    "Users",
                    "SavedSearches"
                ],
                "summary": "List the user's saved searches",
                "description": "Paginated. Each row includes the notifications sub-array. By default returns active + paused (snoozed) searches; the SPA can filter client-side.",
                "operationId": "9f33d92c8548b48e53785928695a6ae7",
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "maximum": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated saved-search list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Users",
                    "SavedSearches"
                ],
                "summary": "Create a new saved search",
                "description": "Body: label (required), query_text, filters_json, notifications (optional array of {channel, frequency, enabled}). Enforces a cap of 25 active saved searches per user — over-cap returns 422.",
                "operationId": "66828f26941cac67806a32a777898ee6",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "label"
                                ],
                                "properties": {
                                    "label": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "query_text": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 500
                                    },
                                    "filters_json": {
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "notifications": {
                                        "type": "array",
                                        "items": {
                                            "properties": {
                                                "channel": {
                                                    "type": "string",
                                                    "maxLength": 50
                                                },
                                                "frequency": {
                                                    "type": "string",
                                                    "maxLength": 200
                                                },
                                                "enabled": {
                                                    "type": "boolean"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created saved-search.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure or cap reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/saved-searches/{saved_search_id}": {
            "delete": {
                "tags": [
                    "Users",
                    "SavedSearches"
                ],
                "summary": "Hard-delete a saved search (and its notifications)",
                "description": "Hard delete — the schema's CASCADE FK removes all notification rows automatically. If you want to keep the search but stop it from firing, PATCH `active: false` instead (snooze).",
                "operationId": "3c026fdae78008959ec375762ca6ca92",
                "parameters": [
                    {
                        "name": "saved_search_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted (idempotent).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "tags": [
                    "Users",
                    "SavedSearches"
                ],
                "summary": "Update a saved search",
                "description": "Mutable: label, query_text, filters_json, active (snooze toggle). If `notifications` is present in the body, it REPLACES the entire notification set (delete existing, insert new). To keep an existing notification unchanged, echo it back in the array.",
                "operationId": "e961fafd2075fcf1d01f827f9e10c99c",
                "parameters": [
                    {
                        "name": "saved_search_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "label": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 100
                                    },
                                    "query_text": {
                                        "type": "string",
                                        "nullable": true,
                                        "maxLength": 500
                                    },
                                    "filters_json": {
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "active": {
                                        "type": "boolean"
                                    },
                                    "notifications": {
                                        "description": "Full replacement set — each item is a notification-preference row {channel, enabled, throttle_minutes, ...}. Shape validated at the controller layer; kept as a free object here so the FE can evolve the preference model without a spec change.",
                                        "type": "array",
                                        "items": {
                                            "type": "object"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated saved-search.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Saved search not found or not owned by caller.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/saved-searches/{saved_search_id}/run": {
            "post": {
                "tags": [
                    "Users",
                    "SavedSearches"
                ],
                "summary": "Re-execute a saved search and return results",
                "description": "Runs the stored query + filters through the same PostingStore pipeline as /api/v1/jobs/search — honoring the campaign_live_providers + campaign_fq_clause cache guards, so /run only surfaces billable inventory (identical semantics to a fresh search). Updates last_result_count on the saved search. Returns the same shape as /jobs/search.",
                "operationId": "4a2f1e68c143f134a7d114425986bcc8",
                "parameters": [
                    {
                        "name": "saved_search_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "maximum": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Search results (same shape as /jobs/search).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Saved search not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Search temporarily unavailable (Solr).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/users/search-history": {
            "get": {
                "tags": [
                    "Users",
                    "SearchHistory"
                ],
                "summary": "List the logged-in consumer's recent searches",
                "description": "Paginated, newest first. Rows outside the 90-day rolling retention window may be missing (the purge command drops them nightly). Each row includes the query text, filters JSON, and the result count at search time.",
                "operationId": "0f9d15576c0b48d0ca451de5c0c267f2",
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "maximum": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated history list.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Users",
                    "SearchHistory"
                ],
                "summary": "Hard-clear the user's entire search history",
                "description": "Immediate hard delete — no soft flag, no retention grace. Privacy-sensitive by design: the user asked for their history to go away, so it goes away. Idempotent — a repeat call on an already-empty history still returns 200.",
                "operationId": "3300e99421bd489689583c62f27b868a",
                "responses": {
                    "200": {
                        "description": "Cleared (idempotent).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication required.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonEnvelope"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "AdminUser": {
                "title": "Admin User",
                "description": "Internal staff login. Distinct from juju.user (consumer) and sponsor_login / publisher_login (portal humans).",
                "required": [
                    "user_id",
                    "username",
                    "email",
                    "role",
                    "active"
                ],
                "properties": {
                    "user_id": {
                        "description": "admin.admin_user.admin_user_id renamed to user_id on the wire.",
                        "type": "integer"
                    },
                    "username": {
                        "description": "Immutable after creation — audit-log continuity.",
                        "type": "string"
                    },
                    "first_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "last_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "phone": {
                        "description": "E.164 normalized.",
                        "type": "string",
                        "nullable": true
                    },
                    "role": {
                        "type": "string",
                        "example": "admin"
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_last_login": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "ConsentDocument": {
                "title": "Consent Document",
                "description": "A versioned consent disclosure (Terms of Service, marketing/SMS opt-in, offer-specific consent). Immutable — a new version is published rather than edited in place.",
                "required": [
                    "consent_document_id",
                    "consent_type",
                    "version",
                    "active",
                    "date_created"
                ],
                "properties": {
                    "consent_document_id": {
                        "description": "juju.consent_document — a versioned, immutable legal disclosure.\n\nList responses omit body_html / partners / sms_disclosure (they can be\nlarge); a single-document GET includes them. Declared nullable here so the\none schema serves both shapes.",
                        "type": "integer"
                    },
                    "consent_type": {
                        "type": "string",
                        "example": "terms_of_service"
                    },
                    "version": {
                        "type": "string",
                        "example": "2026-08-18"
                    },
                    "offer_id": {
                        "description": "Set only for offer-specific consents; null for site-level.",
                        "type": "integer",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "body_html": {
                        "description": "Full disclosure (single-document GET only). Plain text or HTML.",
                        "type": "string",
                        "nullable": true
                    },
                    "partners": {
                        "description": "TCPA partner snapshot (single-document GET only).",
                        "type": "array",
                        "items": {
                            "type": "object"
                        },
                        "nullable": true
                    },
                    "sms_disclosure": {
                        "description": "Mandatory SMS copy (single-document GET only).",
                        "type": "string",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "ConsumerUser": {
                "title": "Consumer User",
                "description": "One row of juju.user — a consumer / jobseeker account. On the admin surface (support / ops). Detail adds info + activity blocks.",
                "required": [
                    "user_id",
                    "email",
                    "active"
                ],
                "properties": {
                    "user_id": {
                        "description": "Consumer user row — juju.user (jobseeker accounts, viewed on the admin\nsurface for support / ops). Detail view layers `info` (juju.user_info)\nand `activity` blocks on top.\n\nNamed ConsumerUser to distinguish from AdminUser / SponsorLogin /\nPublisherLogin. All four are distinct login tables.\n\nSee JuJu\\Admin\\Controllers\\V1\\Users::shape_list_row().",
                        "type": "integer"
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "first_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "last_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "country": {
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_verified": {
                        "description": "Non-null when the email artifact has completed verification.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "date_last_login": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "mfa_method": {
                        "type": "string",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "Lookups": {
                "title": "Admin Lookups",
                "description": "Form-population data for the admin SPA — one call returns every dropdown/enum the surface needs. Cached ~5min. Every block uses `label` as the display field for SPA-side dropdown consistency (as of 2026-08-03).",
                "required": [
                    "campaign_budget_types",
                    "job_partners",
                    "work_types",
                    "job_groups",
                    "offer_priority_tiers"
                ],
                "properties": {
                    "campaign_budget_types": {
                        "description": "Hardcoded — mirrors the CHECK enum on sponsor.job_provider_campaign.budget_type.",
                        "type": "array",
                        "items": {
                            "required": [
                                "value",
                                "label"
                            ],
                            "properties": {
                                "value": {
                                    "description": "Aggregate lookups response — GET /admin/v1/lookups.\n\nSee JuJu\\Admin\\Controllers\\V1\\Lookups::all() for the source of truth.\nCached ~5min in Memcached.",
                                    "type": "string",
                                    "enum": [
                                        "daily",
                                        "monthly",
                                        "flight",
                                        "unlimited"
                                    ]
                                },
                                "label": {
                                    "type": "string"
                                }
                            },
                            "type": "object"
                        }
                    },
                    "job_partners": {
                        "description": "Rows from sponsor.job_partner (WHERE active=true). Uses `label` for consistency with other lookup blocks (2026-08-03).",
                        "type": "array",
                        "items": {
                            "required": [
                                "job_partner_id",
                                "label"
                            ],
                            "properties": {
                                "job_partner_id": {
                                    "type": "integer"
                                },
                                "label": {
                                    "type": "string"
                                },
                                "website": {
                                    "type": "string",
                                    "nullable": true
                                },
                                "documentation": {
                                    "type": "string",
                                    "nullable": true
                                }
                            },
                            "type": "object"
                        }
                    },
                    "work_types": {
                        "type": "array",
                        "items": {
                            "required": [
                                "work_type_id",
                                "label"
                            ],
                            "properties": {
                                "work_type_id": {
                                    "type": "integer"
                                },
                                "label": {
                                    "type": "string"
                                }
                            },
                            "type": "object"
                        }
                    },
                    "job_groups": {
                        "description": "jobs.job_group rows with SOC codes for occupational-taxonomy targeting.",
                        "type": "array",
                        "items": {
                            "required": [
                                "job_group_id",
                                "label"
                            ],
                            "properties": {
                                "job_group_id": {
                                    "type": "integer"
                                },
                                "label": {
                                    "type": "string"
                                },
                                "soc_code": {
                                    "type": "string",
                                    "nullable": true
                                }
                            },
                            "type": "object"
                        }
                    },
                    "offer_priority_tiers": {
                        "description": "offer.offer_priority_tier rows (WHERE active=true), Diamond → Dust. Populates the offer-create tier dropdown.",
                        "type": "array",
                        "items": {
                            "required": [
                                "priority_tier_id",
                                "label",
                                "display_rank"
                            ],
                            "properties": {
                                "priority_tier_id": {
                                    "type": "integer"
                                },
                                "label": {
                                    "type": "string"
                                },
                                "display_rank": {
                                    "type": "integer"
                                }
                            },
                            "type": "object"
                        }
                    }
                },
                "type": "object"
            },
            "Notification": {
                "title": "Notification",
                "description": "A shared admin alert with an open → acknowledged → resolved/dismissed lifecycle.",
                "required": [
                    "notification_id",
                    "type",
                    "severity",
                    "title",
                    "status"
                ],
                "properties": {
                    "notification_id": {
                        "description": "Notification row — admin.notification. The shared team inbox item.",
                        "type": "integer"
                    },
                    "type": {
                        "type": "string",
                        "example": "feed_failed"
                    },
                    "severity": {
                        "type": "string",
                        "enum": [
                            "info",
                            "warning",
                            "critical"
                        ]
                    },
                    "title": {
                        "type": "string"
                    },
                    "body": {
                        "type": "string",
                        "nullable": true
                    },
                    "context": {
                        "description": "Structured payload for deep-linking, e.g. {\"provider_id\": 5}.",
                        "type": "object",
                        "nullable": true
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "open",
                            "acknowledged",
                            "resolved",
                            "dismissed"
                        ]
                    },
                    "occurrence_count": {
                        "description": "How many times this (deduped) event fired while open.",
                        "type": "integer"
                    },
                    "last_occurred_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "acknowledged_by": {
                        "type": "integer",
                        "nullable": true
                    },
                    "acknowledged_by_username": {
                        "type": "string",
                        "nullable": true
                    },
                    "acknowledged_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "resolved_by": {
                        "type": "integer",
                        "nullable": true
                    },
                    "resolved_by_username": {
                        "type": "string",
                        "nullable": true
                    },
                    "resolved_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "resolution_note": {
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Offer": {
                "title": "Offer",
                "description": "Main offer entity. Targeting scalars, priority tier + weight, compliance flags, timezone, and lockout window live on the row itself; schedule windows and zipcode allowlist live under /offers/{id}/schedules and /offers/{id}/zipcodes respectively.",
                "required": [
                    "offer_id",
                    "offer_partner_id",
                    "name",
                    "priority_tier_id",
                    "tier_weight",
                    "timezone",
                    "active",
                    "paused"
                ],
                "properties": {
                    "offer_id": {
                        "description": "Offer row — offer.offer. The main entity of Wave 3.\n\nMoney fields (payout) return as string. Ages / age-array return as\ninteger / integer[]. Schedule rows and zipcode allowlist live on\nseparate nested endpoints (they're 1:N children).",
                        "type": "integer"
                    },
                    "offer_partner_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "headline": {
                        "type": "string",
                        "nullable": true
                    },
                    "body": {
                        "type": "string",
                        "nullable": true
                    },
                    "offer_logo": {
                        "description": "Logo image URL for the offer creative (was offer_url; repurposed 2026-08-28).",
                        "type": "string",
                        "nullable": true
                    },
                    "call_now_number": {
                        "description": "Phone-based CTA when set.",
                        "type": "string",
                        "nullable": true
                    },
                    "questions": {
                        "description": "Array of question definitions. Each item: {key, label, type, required, answer_options, disqualifying_answers}.",
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "criteria": {
                        "description": "Free-form JSONB targeting rules.",
                        "type": "object"
                    },
                    "min_age": {
                        "type": "integer",
                        "nullable": true
                    },
                    "max_age": {
                        "type": "integer",
                        "nullable": true
                    },
                    "excluded_ages": {
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "nullable": true
                    },
                    "priority_tier_id": {
                        "type": "integer"
                    },
                    "tier_weight": {
                        "description": "1..100 — weighted-random share within the tier.",
                        "type": "integer"
                    },
                    "min_impressions_per_hour": {
                        "description": "Floor guarantee — offer catches up if under this in the current hour.",
                        "type": "integer",
                        "nullable": true
                    },
                    "payout": {
                        "description": "Money as string (exact DB DECIMAL).",
                        "type": "string",
                        "example": "12.50",
                        "nullable": true
                    },
                    "daily_cap": {
                        "type": "integer",
                        "nullable": true
                    },
                    "lockout_days": {
                        "description": "Post-conversion suppression window. Null = no lockout.",
                        "type": "integer",
                        "nullable": true
                    },
                    "requires_trusted_form": {
                        "type": "boolean"
                    },
                    "requires_jornaya": {
                        "type": "boolean"
                    },
                    "requires_preping": {
                        "description": "When true, controller pre-pings partner at submit time before writing the conversion.",
                        "type": "boolean"
                    },
                    "timezone": {
                        "description": "IANA name; DST-correct schedule matching.",
                        "type": "string"
                    },
                    "start_date": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "end_date": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "test_mode": {
                        "type": "boolean"
                    },
                    "paused": {
                        "type": "boolean"
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_updated": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "OfferList": {
                "title": "Offer List",
                "description": "Named bundle of offers. Assigned to sponsors (as allow/block) and to publishers (with priority) so the matcher routes traffic to the right offers based on the serving context. See docs/wave3-schema-plan.md §\"Offer lists\" for the matcher rules.",
                "required": [
                    "offer_list_id",
                    "name",
                    "active"
                ],
                "properties": {
                    "offer_list_id": {
                        "description": "OfferList row — offer.offer_list. Named bundle of offers, assigned\nto sponsor and publisher contexts for serving-layer routing.\n\nDetail responses layer a `counts` object on top of the base row with\nthe four junction cardinalities (active offers, allowlisted sponsors,\nblocklisted sponsors, publishers).",
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "counts": {
                        "description": "Membership tallies — only present on the detail response, not list rows. `offers` counts junction rows where BOTH the junction and the parent offer are active (matches what the matcher would consider); use `include_inactive` on the nested /offers endpoint to see the full set.",
                        "properties": {
                            "offers": {
                                "type": "integer"
                            },
                            "sponsors_allow": {
                                "type": "integer"
                            },
                            "sponsors_block": {
                                "type": "integer"
                            },
                            "publishers": {
                                "type": "integer"
                            }
                        },
                        "type": "object"
                    }
                },
                "type": "object"
            },
            "OfferListMember": {
                "title": "Offer List Member",
                "description": "Junction row from offer.offer_list_offer joined to a summary of the parent offer — enough for the admin members-panel display.",
                "required": [
                    "offer_id",
                    "offer_list_id",
                    "weight",
                    "active",
                    "offer_active"
                ],
                "properties": {
                    "offer_list_id": {
                        "description": "One row of an offer-list membership view (the offer-in-list junction).\nCombines the junction row (weight, position, active) with a small\nsummary of the parent offer so the admin UI can render the members\npanel without a second fetch.",
                        "type": "integer"
                    },
                    "offer_id": {
                        "type": "integer"
                    },
                    "weight": {
                        "description": "1..100 — weighted-random share within the containing list.",
                        "type": "integer"
                    },
                    "position": {
                        "type": "integer",
                        "nullable": true
                    },
                    "active": {
                        "description": "Junction row active flag.",
                        "type": "boolean"
                    },
                    "offer_name": {
                        "type": "string"
                    },
                    "offer_headline": {
                        "type": "string",
                        "nullable": true
                    },
                    "offer_active": {
                        "description": "Parent offer.active — inactive offers are hidden from members lists by default (use include_inactive=true to see them).",
                        "type": "boolean"
                    },
                    "offer_paused": {
                        "type": "boolean"
                    },
                    "offer_payout": {
                        "type": "string",
                        "example": "12.50",
                        "nullable": true
                    },
                    "offer_tier_id": {
                        "type": "integer"
                    },
                    "offer_partner_id": {
                        "type": "integer"
                    }
                },
                "type": "object"
            },
            "OfferPartner": {
                "title": "Offer Partner",
                "description": "Partner org that owns offers. Contains contact info + per-partner defaults that pre-fill new offers.",
                "required": [
                    "offer_partner_id",
                    "name",
                    "active"
                ],
                "properties": {
                    "offer_partner_id": {
                        "description": "OfferPartner row — offer.offer_partner. Contact info + create-only\noffer_defaults.\n\nSee JuJu\\Admin\\Controllers\\V1\\OfferPartners::shape().",
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "logo_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "contact_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "contact_email": {
                        "description": "Denormalized from juju.email artifact.",
                        "type": "string",
                        "format": "email",
                        "nullable": true
                    },
                    "contact_phone": {
                        "description": "Denormalized from juju.phone artifact (E.164).",
                        "type": "string",
                        "nullable": true
                    },
                    "offer_defaults": {
                        "description": "Free-form JSONB used to pre-fill new offers under this partner. Create-only — admin form deep-merges this into a new-offer form; editing an existing offer does not re-apply defaults.",
                        "type": "object",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "OfferSchedule": {
                "title": "Offer Schedule Window",
                "description": "One active window for an offer on a given day of week. Multiple rows per day OK (split shifts). Times interpreted in offer.timezone; NO row for a day = offer inactive that day.",
                "required": [
                    "offer_schedule_id",
                    "offer_id",
                    "day_of_week",
                    "start_time",
                    "end_time"
                ],
                "properties": {
                    "offer_schedule_id": {
                        "description": "OfferSchedule row — offer.offer_schedule. Per-day time-of-day\nwindow. Times are wall-clock in the parent offer's timezone.",
                        "type": "integer"
                    },
                    "offer_id": {
                        "type": "integer"
                    },
                    "day_of_week": {
                        "description": "0=Sun … 6=Sat (PG EXTRACT(DOW) convention).",
                        "type": "integer"
                    },
                    "start_time": {
                        "description": "HH:MM:SS wall-clock in offer.timezone.",
                        "type": "string"
                    },
                    "end_time": {
                        "description": "HH:MM:SS wall-clock in offer.timezone.",
                        "type": "string"
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "ProviderStatus": {
                "title": "Provider Status",
                "description": "A job provider with its serving state, active-campaign budgets, and current indexed job count.",
                "required": [
                    "provider_id",
                    "provider_name",
                    "serving_paid",
                    "serving_organic",
                    "jobs_in_index",
                    "campaigns"
                ],
                "properties": {
                    "provider_id": {
                        "description": "Per-provider row of GET /admin/v1/system/provider-status — mirrors the\nprovider structure JuJu\\Common\\Libraries\\ProviderStatusReport::build()\nemits. Serving flags + campaign budgets come from the sponsor:refresh-budgets\ncache; jobs_in_index comes fresh from Solr.",
                        "type": "integer"
                    },
                    "provider_name": {
                        "type": "string"
                    },
                    "serving_paid": {
                        "description": "Provider has at least one live, in-budget paid campaign (campaign_live_providers).",
                        "type": "boolean"
                    },
                    "serving_organic": {
                        "description": "Provider runs an active organic campaign (campaign_organic_providers).",
                        "type": "boolean"
                    },
                    "jobs_in_index": {
                        "description": "Live document count for this provider in Solr — the served inventory, independent of campaign eligibility. 0 when the Solr count failed (see meta.solr_error).",
                        "type": "integer"
                    },
                    "campaigns": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ProviderStatusCampaign"
                        }
                    }
                },
                "type": "object"
            },
            "ProviderStatusCampaign": {
                "title": "Provider Status Campaign",
                "description": "Budget snapshot for one active campaign. Spend + budget are the sponsor:refresh-budgets cache values (not recomputed); remaining = budget − spent. Money as strings.",
                "required": [
                    "campaign_id",
                    "campaign_name",
                    "budget_type",
                    "pricing_model",
                    "state"
                ],
                "properties": {
                    "campaign_id": {
                        "description": "One active campaign's budget line within a ProviderStatus row — mirrors\nJuJu\\Common\\Libraries\\ProviderStatusReport::campaign_row() after the admin\ncontroller renders money as strings.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "campaign_name": {
                        "type": "string"
                    },
                    "budget_type": {
                        "type": "string",
                        "enum": [
                            "daily",
                            "monthly",
                            "flight",
                            "unlimited"
                        ]
                    },
                    "pricing_model": {
                        "type": "string",
                        "enum": [
                            "cpc",
                            "cpa"
                        ]
                    },
                    "organic": {
                        "type": "boolean"
                    },
                    "paused": {
                        "description": "Manually paused by an operator (distinct from over-budget).",
                        "type": "boolean"
                    },
                    "budget": {
                        "description": "Money as string. Null when budget_type=unlimited.",
                        "type": "string",
                        "example": "500.00",
                        "nullable": true
                    },
                    "spent": {
                        "description": "Spend this budget period (money as string). Null when there is no fresh spend snapshot — a manually-paused campaign, or the refresh has not run.",
                        "type": "string",
                        "example": "318.24",
                        "nullable": true
                    },
                    "remaining": {
                        "description": "budget − spent (money as string). Null for unlimited or when spend is unknown.",
                        "type": "string",
                        "example": "181.76",
                        "nullable": true
                    },
                    "state": {
                        "description": "unknown = active + non-paused but no fresh spend snapshot yet.",
                        "type": "string",
                        "enum": [
                            "in-budget",
                            "over-budget",
                            "paused",
                            "unlimited",
                            "unknown"
                        ]
                    }
                },
                "type": "object"
            },
            "Publisher": {
                "title": "Publisher",
                "description": "A publisher company. Detail view adds accounts[] and earnings_summary.",
                "required": [
                    "publisher_id",
                    "name",
                    "active"
                ],
                "properties": {
                    "publisher_id": {
                        "description": "Publisher row — publisher.publisher (the org table). Detail responses\nlayer `accounts` (array of PublisherAccount) and `earnings_summary`\non top of this base.\n\nSee JuJu\\Admin\\Controllers\\V1\\Publishers::shape() and ::fetch_detail().",
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "address1": {
                        "type": "string",
                        "nullable": true
                    },
                    "address2": {
                        "type": "string",
                        "nullable": true
                    },
                    "city": {
                        "type": "string",
                        "nullable": true
                    },
                    "state": {
                        "type": "string",
                        "nullable": true
                    },
                    "postal": {
                        "type": "string",
                        "nullable": true
                    },
                    "country": {
                        "type": "string",
                        "nullable": true
                    },
                    "website": {
                        "type": "string",
                        "nullable": true
                    },
                    "primary_contact": {
                        "type": "string",
                        "nullable": true
                    },
                    "primary_email": {
                        "type": "string",
                        "nullable": true
                    },
                    "primary_phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "PublisherLogin": {
                "title": "Publisher Login",
                "description": "One human login for the publisher self-service portal. Distinct from PublisherAccount (API-key credentials for server-to-server) — this is the humans who log in via the portal.",
                "required": [
                    "user_id",
                    "username",
                    "email",
                    "publisher_id",
                    "active"
                ],
                "properties": {
                    "user_id": {
                        "description": "publisher_login_id renamed to user_id on the wire.",
                        "type": "integer"
                    },
                    "username": {
                        "type": "string"
                    },
                    "first_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "last_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "publisher_id": {
                        "type": "integer"
                    },
                    "publisher_name": {
                        "description": "Denormalized from publisher.publisher for display.",
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_last_login": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "RunInfo": {
                "title": "Feed Run",
                "description": "One row of jobs.run_info — per-feed-run telemetry produced by feed:process + feed:worker. A run is in-progress when time_processing_finished is null; stuck when workers_last_heartbeat is stale (>5 min) against a null time_processing_finished.",
                "required": [
                    "run_id",
                    "job_provider_id",
                    "workers_active"
                ],
                "properties": {
                    "run_id": {
                        "description": "Feed-run row shape — mirrors JuJu\\Admin\\Controllers\\V1\\FeedRuns::shape()\nand JuJu\\Admin\\Controllers\\V1\\Providers::shape_run_info(). One wire\nform regardless of whether the row is embedded in a provider detail\nor listed on the /feed-runs endpoint.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "job_provider_id": {
                        "type": "integer"
                    },
                    "job_provider": {
                        "description": "Provider display name (sponsor.job_provider.job_provider).",
                        "type": "string"
                    },
                    "total_jobs_in_file": {
                        "description": "Count of <capture_node> elements the feed contained. Null until parse completes.",
                        "type": "integer",
                        "nullable": true
                    },
                    "new_jobs_in_file": {
                        "type": "integer",
                        "nullable": true
                    },
                    "updated_jobs_in_file": {
                        "type": "integer",
                        "nullable": true
                    },
                    "time_started": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "time_parse_finished": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "time_processing_finished": {
                        "description": "Null while the run is in progress; timestamped on completion.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "workers_active": {
                        "type": "integer",
                        "example": 0
                    },
                    "workers_last_heartbeat": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "Segment": {
                "title": "Campaign Segment",
                "description": "One segment under a campaign — a targeting criteria + bid-range pair.",
                "required": [
                    "segment_id",
                    "campaign_id",
                    "name",
                    "bid_low",
                    "bid_high",
                    "active"
                ],
                "properties": {
                    "segment_id": {
                        "description": "Campaign segment row — sponsor.job_provider_campaign_segment.\nUsed by JuJu\\Admin\\Controllers\\V1\\Campaigns (nested list/create) and\nJuJu\\Admin\\Controllers\\V1\\Segments (flat CRUD).",
                        "type": "integer"
                    },
                    "campaign_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "criteria": {
                        "description": "JSONB targeting criteria (e.g. {\"job_group_id\": [123], \"state\": [\"CA\"]}). Shape is caller-defined and evolves with the matcher; treat as opaque object.",
                        "type": "object",
                        "nullable": true
                    },
                    "bid_low": {
                        "description": "Money as string (exact DB DECIMAL). On a CPA campaign these bounds are denominated in CPA dollars (the feed payout), not per-click.",
                        "type": "string",
                        "example": "0.12"
                    },
                    "bid_high": {
                        "type": "string",
                        "example": "0.42"
                    },
                    "prefer_high_bid": {
                        "type": "boolean"
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "conversion_rate_assumed": {
                        "description": "CPA only. Admin-seeded conversion rate (fraction 0–1) used to back out the CPC and as the working rate when tuning is off.",
                        "type": "string",
                        "example": "0.040000",
                        "nullable": true
                    },
                    "conversion_rate_working": {
                        "description": "CPA only. The rate currently in force at serve time — observation-tuned when tuning is on, else mirrors the assumed rate. Read-only (maintained by the reconcile worker / rate-config writes).",
                        "type": "string",
                        "example": "0.037500",
                        "nullable": true
                    },
                    "effective_cpc_override": {
                        "description": "CPA only. Admin manual CPC that wins outright over the backout when set. Money as string.",
                        "type": "string",
                        "example": "1.20",
                        "nullable": true
                    },
                    "observation_tuning_enabled": {
                        "description": "CPA only. When true, observed conversions drive conversion_rate_working; when false it stays pinned to the assumed rate.",
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "Sponsor": {
                "title": "Sponsor",
                "description": "Top-level sponsor / job-partner org. Detail view adds provider_count.",
                "required": [
                    "job_partner_id",
                    "name",
                    "active"
                ],
                "properties": {
                    "job_partner_id": {
                        "description": "DB FK column name preserved for alignment with sponsor.* — the resource itself is a Sponsor.",
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "website": {
                        "type": "string",
                        "nullable": true
                    },
                    "documentation": {
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "SponsorLogin": {
                "title": "Sponsor Login",
                "description": "One human login for the sponsor self-service portal. Scoped to a parent sponsor org (job_partner_id, required). Optionally further scoped to a single provider (job_provider_id, nullable — omit for org-wide access across every provider under the partner). Distinct from AdminUser (staff) and from the API-key accounts used for server-to-server integration.",
                "required": [
                    "user_id",
                    "username",
                    "email",
                    "job_partner_id",
                    "active"
                ],
                "properties": {
                    "user_id": {
                        "description": "sponsor_login_id renamed to user_id on the wire.",
                        "type": "integer"
                    },
                    "username": {
                        "type": "string"
                    },
                    "first_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "last_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "job_partner_id": {
                        "description": "Parent sponsor org. Required — every login belongs to one partner.",
                        "type": "integer"
                    },
                    "job_partner_name": {
                        "description": "Denormalized from sponsor.job_partner for display.",
                        "type": "string"
                    },
                    "job_provider_id": {
                        "description": "Optional sub-account restriction. Null = org-wide access.",
                        "type": "integer",
                        "nullable": true
                    },
                    "job_provider_name": {
                        "description": "Denormalized from sponsor.job_provider for display.",
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_last_login": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "UserActivity": {
                "title": "Consumer User Activity",
                "description": "Activity summary for the support / ops drill-down. clicks_last_90d is bounded to keep partition scans reasonable; leads is a placeholder until Wave 3 ships the leads.lead table.",
                "required": [
                    "saved_jobs",
                    "saved_searches",
                    "search_history_in_window",
                    "clicks_last_90d",
                    "leads"
                ],
                "properties": {
                    "saved_jobs": {
                        "description": "Consumer user activity counts — nested block on the consumer user\ndetail response.\n\nSee JuJu\\Admin\\Controllers\\V1\\Users::fetch_activity() + display().",
                        "type": "integer"
                    },
                    "saved_searches": {
                        "type": "integer"
                    },
                    "search_history_in_window": {
                        "description": "90-day retention — surviving rows are all in-window.",
                        "type": "integer"
                    },
                    "clicks_last_90d": {
                        "type": "integer"
                    },
                    "leads": {
                        "description": "Placeholder — always 0 until Wave 3 leads schema lands.",
                        "type": "integer"
                    },
                    "last_login": {
                        "description": "Mirror of the top-level date_last_login, surfaced here for SPA convenience.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "UserInfo": {
                "title": "Consumer User Info",
                "description": "Extended profile data (juju.user_info) — demographics, address, gender lookup. Null on the parent response when no user_info row exists.",
                "properties": {
                    "date_of_birth": {
                        "description": "Extended consumer PII — juju.user_info. Nested block on the consumer\nuser detail response. Null when the user has never filled out an\ninfo-requiring form flow.\n\nSee JuJu\\Admin\\Controllers\\V1\\Users::fetch_user_info().",
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "gender_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "gender_code": {
                        "type": "string",
                        "nullable": true
                    },
                    "gender_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "gender_other": {
                        "type": "string",
                        "nullable": true
                    },
                    "address_1": {
                        "type": "string",
                        "nullable": true
                    },
                    "address_2": {
                        "type": "string",
                        "nullable": true
                    },
                    "city_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "state_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "zipcode_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "raw_city": {
                        "type": "string",
                        "nullable": true
                    },
                    "raw_state": {
                        "type": "string",
                        "nullable": true
                    },
                    "raw_postal": {
                        "type": "string",
                        "nullable": true
                    },
                    "extra_attributes": {
                        "description": "JSONB — form-specific fields captured outside the fixed schema.",
                        "type": "object",
                        "nullable": true
                    },
                    "date_updated": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "JsonEnvelope": {
                "title": "JSON Envelope",
                "description": "Standard response wrapper used by every JuJu API surface. Endpoints override the `data` property with their specific payload shape via allOf composition; `meta` and `errors` are uniform.",
                "required": [
                    "data",
                    "meta",
                    "errors"
                ],
                "properties": {
                    "data": {
                        "description": "Endpoint-specific payload. Overridden per endpoint with the actual shape; this base schema leaves it untyped so each endpoint can supply object / array / scalar / null.",
                        "nullable": true
                    },
                    "meta": {
                        "description": "Pagination and context metadata. Always present, empty object ({}) when no metadata applies to the response.",
                        "type": "object"
                    },
                    "errors": {
                        "description": "Empty array on success. On failure, human-readable error strings suitable for surfacing to end users.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": []
                    }
                },
                "type": "object"
            },
            "Adjustment": {
                "title": "Adjustment",
                "description": "A manual credit or debit against a sponsor or publisher account.",
                "required": [
                    "adjustment_id",
                    "account_type",
                    "account_ref",
                    "direction",
                    "amount",
                    "reason",
                    "status"
                ],
                "properties": {
                    "adjustment_id": {
                        "description": "Adjustment row — billing.adjustment. An operator-issued credit/debit against\na sponsor or publisher account (e.g. a bot-click reconciliation credit).",
                        "type": "integer"
                    },
                    "account_type": {
                        "type": "string",
                        "enum": [
                            "sponsor",
                            "publisher"
                        ]
                    },
                    "account_ref": {
                        "description": "job_partner_id (sponsor) or publisher_id (publisher).",
                        "type": "integer"
                    },
                    "direction": {
                        "type": "string",
                        "enum": [
                            "credit",
                            "debit"
                        ]
                    },
                    "amount": {
                        "type": "string",
                        "example": "125.0000"
                    },
                    "currency": {
                        "type": "string",
                        "example": "USD"
                    },
                    "reason": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "applied",
                            "void"
                        ]
                    },
                    "applied_invoice_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "applied_payout_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Campaign": {
                "title": "Campaign",
                "description": "Sponsor-side targeting + budget config driving what /jobs/search serves.",
                "required": [
                    "campaign_id",
                    "job_provider_id",
                    "name",
                    "budget_type",
                    "active",
                    "paused"
                ],
                "properties": {
                    "campaign_id": {
                        "description": "Campaign row — sponsor.job_provider_campaign. Detail responses layer\n`segments` (array of Segment) and `spend_to_date` on top of this base.\n\nUsed by both /admin/v1/campaigns and /sponsor/v1/campaigns so lives\nin common — per-scope openapi generation only scans juju/common +\njuju/{scope}, and sponsor's scope doesn't see admin/Schemas.",
                        "type": "integer"
                    },
                    "job_provider_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "paused": {
                        "type": "boolean"
                    },
                    "test_mode": {
                        "type": "boolean"
                    },
                    "promotional": {
                        "type": "boolean"
                    },
                    "organic": {
                        "type": "boolean"
                    },
                    "budget_type": {
                        "type": "string",
                        "enum": [
                            "daily",
                            "monthly",
                            "flight",
                            "unlimited"
                        ]
                    },
                    "pricing_model": {
                        "description": "How the per-job feed value is interpreted. cpc = cost-per-click (default). cpa = cost-per-application: the value is a CPA payout, backed out to an estimated CPC per segment for pacing.",
                        "type": "string",
                        "enum": [
                            "cpc",
                            "cpa"
                        ]
                    },
                    "budget": {
                        "description": "Money as string (exact DB DECIMAL). Null when budget_type=unlimited.",
                        "type": "string",
                        "example": "500.00",
                        "nullable": true
                    },
                    "default_cpc": {
                        "type": "string",
                        "example": "0.12",
                        "nullable": true
                    },
                    "start_date": {
                        "description": "Required + non-null iff budget_type=flight; null otherwise.",
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "end_date": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_updated": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "EarningsSummary": {
                "title": "Publisher Earnings Summary",
                "description": "Publisher-wide earnings aggregated across every account, banded by month for dashboard display. All amounts are money-as-string; pending_payout is null until payout tracking lands (its shape is stable so the FE never has to move the field).",
                "required": [
                    "to_date",
                    "this_month",
                    "last_month"
                ],
                "properties": {
                    "to_date": {
                        "description": "All-time cumulative earnings.",
                        "type": "string",
                        "example": "12345.67"
                    },
                    "this_month": {
                        "description": "Earnings from date_trunc('month', CURRENT_DATE) onward.",
                        "type": "string",
                        "example": "452.19"
                    },
                    "last_month": {
                        "description": "Earnings across the previous calendar month.",
                        "type": "string",
                        "example": "1210.55"
                    },
                    "pending_payout": {
                        "description": "Null placeholder until payout tracking lands.",
                        "type": "string",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "Invoice": {
                "title": "Invoice",
                "description": "A sponsor invoice for a billing period.",
                "required": [
                    "invoice_id",
                    "public_id",
                    "invoice_number",
                    "job_partner_id",
                    "status",
                    "total"
                ],
                "properties": {
                    "invoice_id": {
                        "description": "Invoice row — billing.invoice. Shared by /admin/v1/billing and the sponsor\nportal. Detail responses layer `line_items` (and admin adds `payments`) on\ntop of this base. Money fields are exact-decimal strings.",
                        "type": "integer"
                    },
                    "public_id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "invoice_number": {
                        "type": "string",
                        "example": "INV-2026-000123"
                    },
                    "job_partner_id": {
                        "type": "integer"
                    },
                    "period_start": {
                        "type": "string",
                        "format": "date"
                    },
                    "period_end": {
                        "type": "string",
                        "format": "date"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "open",
                            "paid",
                            "partially_paid",
                            "void",
                            "uncollectible"
                        ]
                    },
                    "subtotal": {
                        "type": "string",
                        "example": "4211.5500"
                    },
                    "tax_amount": {
                        "type": "string",
                        "example": "0.0000"
                    },
                    "total": {
                        "type": "string",
                        "example": "4211.5500"
                    },
                    "amount_paid": {
                        "type": "string",
                        "example": "0.0000"
                    },
                    "currency": {
                        "type": "string",
                        "example": "USD"
                    },
                    "issued_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "due_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Job": {
                "title": "Job",
                "description": "A single job posting as returned by the public search and show endpoints. Most fields are optional — feeds vary widely in what they populate. The `click_url` field is server-generated and is the ONLY URL consumers should send users to (it routes through click tracking before redirecting to the underlying provider). PUBLISHER (Bearer-authenticated) responses match the syndication feed: `id` is an opaque, stable hash (not the raw compound id); `jobid`, `job_provider_id`, and `jobgroupid` are OMITTED; and a `payout` field is added. Internal / frontend responses use the raw compound `id` and include `jobid` / `job_provider_id` / `jobgroupid` (no `payout`).",
                "required": [
                    "id",
                    "title",
                    "click_url"
                ],
                "properties": {
                    "id": {
                        "description": "PUBLISHER (Bearer) responses: an opaque, stable, non-reversible hash of the job — the same value in search, show, and the feed files. Safe to dedup / update-by-id on; it is NOT the raw compound id and can not be used to fetch a job. INTERNAL / frontend responses: the raw compound Solr id `{job_provider_id}_{jobid}`, usable as the path parameter on /api/v1/jobs/{id}.",
                        "type": "string",
                        "example": "2LKlPuMKB6P6-mivzB8Cuw"
                    },
                    "jobid": {
                        "description": "INTERNAL / frontend only — OMITTED from publisher (Bearer) responses. Provider-supplied job identifier; not globally unique across providers. Typed as a string (feeds use numeric ids, GUIDs, and slugs interchangeably).",
                        "type": "string",
                        "example": "141096464"
                    },
                    "reference": {
                        "description": "Provider-supplied reference / requisition number.",
                        "type": "string",
                        "nullable": true
                    },
                    "job_provider_id": {
                        "description": "INTERNAL / frontend only — OMITTED from publisher (Bearer) responses. Internal id of the sponsor that supplied this job.",
                        "type": "integer",
                        "example": 2
                    },
                    "title": {
                        "type": "string",
                        "example": "CDL-A Truck Drivers - Earn $1,400 Weekly"
                    },
                    "title_display": {
                        "type": "string",
                        "nullable": true
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "company": {
                        "type": "string",
                        "example": "Hogan Transportation",
                        "nullable": true
                    },
                    "logo": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "click_url": {
                        "description": "Server-generated URL to route the user through. ALWAYS use this to send users to a job — the underlying joburl is intentionally not exposed. Hitting click_url records the click (attribution / billing) before 302-redirecting to the provider.",
                        "type": "string",
                        "format": "uri",
                        "example": "https://jobs.juju.com/jobs/click/abc123def456..."
                    },
                    "payout": {
                        "description": "PUBLISHER (Bearer) responses only. Indicative per-click earnings for your account (effective_cpc × your cpc_share), as an exact decimal string. A ranking signal — the actual amount is settled at click time. Absent on internal / frontend responses.",
                        "type": "string",
                        "example": "0.4200",
                        "nullable": true
                    },
                    "city": {
                        "type": "string",
                        "example": "Rueter",
                        "nullable": true
                    },
                    "state": {
                        "type": "string",
                        "example": "Missouri",
                        "nullable": true
                    },
                    "state_code": {
                        "type": "string",
                        "example": "MO",
                        "nullable": true,
                        "maxLength": 2
                    },
                    "province": {
                        "type": "string",
                        "nullable": true
                    },
                    "postal": {
                        "type": "string",
                        "example": "65744",
                        "nullable": true
                    },
                    "country": {
                        "type": "string",
                        "example": "US",
                        "nullable": true
                    },
                    "latitude": {
                        "type": "number",
                        "format": "double",
                        "example": 36.6,
                        "nullable": true
                    },
                    "longitude": {
                        "type": "number",
                        "format": "double",
                        "example": -92.86,
                        "nullable": true
                    },
                    "geo_location": {
                        "description": "Compound \"lat,lon\" string used server-side for Solr radius filtering ({!geofilt}). Auto-derived from latitude + longitude at index time, so it may be absent on jobs whose feed didn't supply coordinates. Clients that need coordinates for map rendering / distance math should read the discrete `latitude` and `longitude` fields — this one is provided for transparency, not as the primary API surface.",
                        "type": "string",
                        "example": "36.600000,-92.860000",
                        "nullable": true
                    },
                    "work_location": {
                        "type": "string",
                        "nullable": true
                    },
                    "is_remote": {
                        "type": "boolean",
                        "nullable": true
                    },
                    "date_posted": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "date_updated": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "date_expires": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "salary_low": {
                        "type": "number",
                        "format": "double",
                        "example": 1400,
                        "nullable": true
                    },
                    "salary_high": {
                        "type": "number",
                        "format": "double",
                        "example": 1400,
                        "nullable": true
                    },
                    "salary_avg": {
                        "type": "number",
                        "format": "double",
                        "example": 1400,
                        "nullable": true
                    },
                    "salary_type": {
                        "type": "string",
                        "example": "week",
                        "nullable": true,
                        "enum": [
                            "hour",
                            "day",
                            "week",
                            "month",
                            "year"
                        ]
                    },
                    "salary_str": {
                        "description": "Human-readable salary range string from the feed if provided.",
                        "type": "string",
                        "nullable": true
                    },
                    "currency": {
                        "type": "string",
                        "example": "USD",
                        "nullable": true,
                        "maxLength": 3
                    },
                    "work_type": {
                        "description": "Human label (e.g. \"Full Time\"), resolved from the stored work-type id.",
                        "type": "string",
                        "example": "Full Time",
                        "nullable": true
                    },
                    "experience_level": {
                        "type": "string",
                        "nullable": true
                    },
                    "education_level": {
                        "type": "string",
                        "nullable": true
                    },
                    "industry": {
                        "type": "string",
                        "nullable": true
                    },
                    "jobgroup": {
                        "type": "string",
                        "nullable": true
                    },
                    "jobgroupid": {
                        "description": "INTERNAL / frontend only — OMITTED from publisher (Bearer) responses.",
                        "type": "integer",
                        "nullable": true
                    },
                    "major_group_id": {
                        "description": "O*NET major-group id (the canonical category taxonomy; labels + counts via /lookups job_groups). Returned to all consumers.",
                        "type": "integer",
                        "nullable": true
                    },
                    "category": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "Driving and Transport"
                        ],
                        "nullable": true
                    },
                    "subcategory": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "Truck Driver"
                        ],
                        "nullable": true
                    },
                    "job_summary": {
                        "type": "string",
                        "nullable": true
                    },
                    "job_requirement": {
                        "type": "string",
                        "nullable": true
                    },
                    "job_experience": {
                        "type": "string",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "OfferDisplay": {
                "title": "Offer (display)",
                "description": "Consumer-facing offer fields for rendering an offer unit + its form. No payout / cap / tier data.",
                "required": [
                    "offer_id"
                ],
                "properties": {
                    "offer_id": {
                        "description": "OfferDisplay — the consumer-safe projection of offer.offer returned by the\noffer-serve endpoints (GET /api/v1/offers/next and /offers/{id}).\n\nDeliberately excludes serving internals (payout, caps, tier weights,\npartner ids). See JuJu\\Webapi\\Controllers\\V1\\Offers\\Serve::shape_display —\nthat allowlist is the source of truth this schema mirrors.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "name": {
                        "description": "Internal-ish label; usually the headline is what renders.",
                        "type": "string",
                        "nullable": true
                    },
                    "headline": {
                        "type": "string",
                        "nullable": true
                    },
                    "body": {
                        "description": "Offer copy (plain text or HTML per the offer).",
                        "type": "string",
                        "nullable": true
                    },
                    "offer_logo": {
                        "description": "Logo image URL for the offer creative.",
                        "type": "string",
                        "nullable": true
                    },
                    "call_now_number": {
                        "description": "Click-to-call number for call offers.",
                        "type": "string",
                        "nullable": true
                    },
                    "questions": {
                        "description": "Form questions to render (offer.questions JSONB). Shape is offer-defined.",
                        "type": "array",
                        "items": {
                            "type": "object"
                        },
                        "nullable": true
                    },
                    "requires_trusted_form": {
                        "description": "SPA must inject the TrustedForm script before submit.",
                        "type": "boolean"
                    },
                    "requires_jornaya": {
                        "description": "SPA must inject the Jornaya (LeadiD) script before submit.",
                        "type": "boolean"
                    },
                    "action": {
                        "description": "How the SPA acts on this offer — server-driven so the SPA never hardcodes where/how to post. `kind` is lead_form | redirect | call. For lead_form and redirect, POST to `url` (a JuJu endpoint) using `method`; for redirect, open the returned `redirect_url` with `target`. For call, dial `call_now_number`.",
                        "properties": {
                            "kind": {
                                "type": "string",
                                "enum": [
                                    "lead_form",
                                    "redirect",
                                    "call"
                                ]
                            },
                            "method": {
                                "type": "string",
                                "example": "POST",
                                "nullable": true
                            },
                            "url": {
                                "description": "Relative JuJu endpoint to POST to (null for call).",
                                "type": "string",
                                "nullable": true
                            },
                            "target": {
                                "description": "_self for in-page form flows, _blank for redirect offers.",
                                "type": "string",
                                "example": "_blank"
                            }
                        },
                        "type": "object"
                    }
                },
                "type": "object"
            },
            "PaginationMeta": {
                "title": "Pagination Meta",
                "description": "Standard pagination meta block emitted by every list endpoint. Populated on responses that return an array of items; empty object `{}` on non-list endpoints.",
                "required": [
                    "total",
                    "page",
                    "per_page",
                    "total_pages"
                ],
                "properties": {
                    "total": {
                        "description": "Total matching rows across all pages.",
                        "type": "integer",
                        "example": 137
                    },
                    "page": {
                        "description": "1-indexed current page number.",
                        "type": "integer",
                        "example": 1
                    },
                    "per_page": {
                        "description": "Rows per page; clamped to the endpoint's max.",
                        "type": "integer",
                        "example": 50
                    },
                    "total_pages": {
                        "description": "ceil(total / per_page). Zero when per_page is zero.",
                        "type": "integer",
                        "example": 3
                    }
                },
                "type": "object"
            },
            "Payment": {
                "title": "Payment",
                "description": "A payment received from a sponsor.",
                "required": [
                    "payment_id",
                    "public_id",
                    "job_partner_id",
                    "amount",
                    "method",
                    "status"
                ],
                "properties": {
                    "payment_id": {
                        "description": "Payment row — billing.payment. Money received from a sponsor (card charge or\nrecorded remittance). Detail responses add `applications` (how it split\nacross invoices).",
                        "type": "integer"
                    },
                    "public_id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "job_partner_id": {
                        "type": "integer"
                    },
                    "amount": {
                        "type": "string",
                        "example": "4211.5500"
                    },
                    "currency": {
                        "type": "string",
                        "example": "USD"
                    },
                    "method": {
                        "type": "string",
                        "enum": [
                            "card",
                            "ach",
                            "check",
                            "wire",
                            "manual"
                        ]
                    },
                    "processor_txn_ref": {
                        "type": "string",
                        "nullable": true
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "succeeded",
                            "failed",
                            "refunded"
                        ]
                    },
                    "received_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "notes": {
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Payout": {
                "title": "Payout",
                "description": "A payout to a publisher for accrued earnings.",
                "required": [
                    "payout_id",
                    "public_id",
                    "publisher_id",
                    "amount",
                    "status"
                ],
                "properties": {
                    "payout_id": {
                        "description": "Payout row — billing.payout. A publisher payout for a period. Shared by\n/admin/v1/billing and the publisher portal. Detail responses add\n`line_items`. Money fields are exact-decimal strings.",
                        "type": "integer"
                    },
                    "public_id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "publisher_id": {
                        "type": "integer"
                    },
                    "period_start": {
                        "type": "string",
                        "format": "date"
                    },
                    "period_end": {
                        "type": "string",
                        "format": "date"
                    },
                    "amount": {
                        "type": "string",
                        "example": "1875.0000"
                    },
                    "currency": {
                        "type": "string",
                        "example": "USD"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "pending",
                            "in_transit",
                            "paid",
                            "failed",
                            "returned",
                            "on_hold"
                        ]
                    },
                    "processor_transfer_ref": {
                        "type": "string",
                        "nullable": true
                    },
                    "initiated_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "paid_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Provider": {
                "title": "Provider",
                "description": "One feed source under a sponsor (sponsor.job_provider). Admin detail view additionally exposes schema_mapping, campaign_count, latest_run, and credential-presence booleans.",
                "required": [
                    "job_provider_id",
                    "job_partner_id",
                    "name",
                    "active",
                    "paused",
                    "fetch_method"
                ],
                "properties": {
                    "job_provider_id": {
                        "description": "Provider row (sponsor.job_provider) — the shape returned by both the\n/providers list and as the base of the /providers/{id} detail. Used\nby admin and sponsor portals.\n\nDetail responses on admin add schema_mapping, campaign_count,\nlatest_run, username_set, password_set. Sponsor exposes only the base\nfields (read-only surface).\n\nNote: `username` / `password` values are NEVER returned — presence\nbooleans on admin detail only.",
                        "type": "integer"
                    },
                    "job_partner_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "feed_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "capture_node": {
                        "description": "XML element name to iterate on when parsing the feed.",
                        "type": "string",
                        "nullable": true
                    },
                    "refresh_minutes": {
                        "type": "integer",
                        "nullable": true
                    },
                    "click_id_param": {
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "last_run_completed": {
                        "description": "Most recent completed run (MAX time_processing_finished). Null when the provider has never had a completed run. Can look stale for a feed whose file rarely changes — see last_checked.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "last_checked": {
                        "description": "Last time the feed file was CHECKED (job_provider_file_hash.date_checked), stamped on every run attempt before the no-change skip. Stays fresh even when the file is unchanged and processing is skipped; last_run_completed does not. Null until first checked.",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "paused": {
                        "type": "boolean"
                    },
                    "force_run": {
                        "type": "boolean"
                    },
                    "fetch_method": {
                        "type": "string",
                        "enum": [
                            "url",
                            "s3",
                            "index"
                        ]
                    },
                    "fetch_config": {
                        "description": "Non-secret transport config. For fetch_method=s3: bucket*, region, role_arn, external_id, credential_source (instance|ssm|static), credentials_ref, object_selection (key|newest_in_prefix), plus key or prefix per selection.",
                        "type": "object",
                        "nullable": true
                    },
                    "has_stored_credentials": {
                        "description": "True if fetch_credentials_encrypted is populated. The credential values themselves are never returned.",
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "PublisherAccount": {
                "title": "Publisher Account",
                "description": "One API-key credential under a publisher. Plaintext keys are returned EXACTLY ONCE on the create + regenerate responses; subsequent GETs return only prefix + hint.",
                "required": [
                    "publisher_account_id",
                    "publisher_id",
                    "account_name",
                    "api_key_prefix",
                    "active"
                ],
                "properties": {
                    "publisher_account_id": {
                        "description": "Publisher API-key account — publisher.publisher_account.\nUsed by both /admin/v1/accounts and /publisher/v1/api-keys endpoints\nso lives in common.\n\nExposes prefix + hint (never plaintext / hash).",
                        "type": "integer"
                    },
                    "publisher_id": {
                        "type": "integer"
                    },
                    "account_name": {
                        "type": "string"
                    },
                    "api_key_prefix": {
                        "type": "string",
                        "example": "juju_pub_XY"
                    },
                    "api_key_hint": {
                        "description": "Last 4 chars of the plaintext key, for UI display (\"…abcd\").",
                        "type": "string",
                        "example": "abcd"
                    },
                    "cpc_share": {
                        "description": "Revenue-share fraction, 0..1, as an exact DECIMAL(5,4) string (NOT a money amount, NOT a percentage). Publisher keeps cpc_share × click cpc; e.g. 0.7000 = 70%. Display as a percentage.",
                        "type": "string",
                        "example": "0.7000"
                    },
                    "rate_limit_tier": {
                        "type": "string",
                        "example": "default"
                    },
                    "organic": {
                        "description": "When true, this publisher's search calls get unpaid / organic inventory mixed in below paid results. Default false (paid-only).",
                        "type": "boolean",
                        "example": false
                    },
                    "min_payout": {
                        "description": "Net payout floor for LIVE serving, as an exact DECIMAL(10,4) string or null. A paid job serves to this account only when its net earning (effective_cpc x cpc_share) is >= this. null = no floor. Distinct from the syndication feed min_cpc, which floors the GROSS effective CPC.",
                        "type": "string",
                        "example": "0.1000",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_last_used": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "PublisherKeyRotation": {
                "title": "Publisher Key Rotation Event",
                "description": "One lifecycle event on a publisher.publisher_account row — rotate, revoke, reactivate, or expire. Audit-trail granularity: who did it, when, and (for rotate) which prefix was replaced.",
                "required": [
                    "rotation_id",
                    "publisher_account_id",
                    "action",
                    "actor_type",
                    "date_created"
                ],
                "properties": {
                    "rotation_id": {
                        "description": "One row of publisher.publisher_key_rotation — a single API-key\nlifecycle event. Shared between the admin and publisher rotation-\nhistory endpoints.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "publisher_account_id": {
                        "type": "integer"
                    },
                    "action": {
                        "type": "string",
                        "enum": [
                            "rotate",
                            "revoke",
                            "reactivate",
                            "expire"
                        ]
                    },
                    "actor_type": {
                        "type": "string",
                        "enum": [
                            "admin",
                            "publisher",
                            "system"
                        ]
                    },
                    "actor_admin_user_id": {
                        "description": "Present when actor_type='admin'.",
                        "type": "integer",
                        "nullable": true
                    },
                    "actor_publisher_login_id": {
                        "description": "Present when actor_type='publisher'.",
                        "type": "integer",
                        "nullable": true
                    },
                    "actor_display": {
                        "description": "Denormalized \"First Last (username)\" or \"system\" for UI display.",
                        "type": "string",
                        "nullable": true
                    },
                    "old_prefix": {
                        "description": "Populated on rotate — the prefix that was replaced.",
                        "type": "string",
                        "nullable": true
                    },
                    "new_prefix": {
                        "description": "Populated on rotate — the prefix now in effect.",
                        "type": "string",
                        "nullable": true
                    },
                    "reason": {
                        "type": "string",
                        "nullable": true
                    },
                    "date_created": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "ReportApiUsageDailyRow": {
                "title": "Daily API Usage Report Row",
                "description": "One day's API request aggregates for a publisher scope.",
                "required": [
                    "report_date",
                    "requests_total"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of a daily-API-usage report. Backed by\nJuJu\\Common\\Libraries\\Reports\\ApiUsageReport::fetch_daily against\n`publisher.api_request_log`.",
                        "type": "string",
                        "format": "date"
                    },
                    "publisher_account_id": {
                        "description": "Present only when group_by includes account.",
                        "type": "integer"
                    },
                    "publisher_account_name": {
                        "description": "Present only when group_by includes account.",
                        "type": "string",
                        "nullable": true
                    },
                    "publisher_id": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "integer"
                    },
                    "publisher_name": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "string",
                        "nullable": true
                    },
                    "requests_total": {
                        "type": "integer"
                    },
                    "requests_2xx": {
                        "type": "integer"
                    },
                    "requests_4xx": {
                        "type": "integer"
                    },
                    "requests_5xx": {
                        "type": "integer"
                    },
                    "avg_response_time_ms": {
                        "description": "Null when no rows in range.",
                        "type": "integer",
                        "nullable": true
                    },
                    "results_returned_total": {
                        "description": "Sum of result_count across all requests.",
                        "type": "integer"
                    }
                },
                "type": "object"
            },
            "ReportClicksDailyRow": {
                "title": "Daily Clicks Report Row",
                "description": "One day's click aggregates. All money as string DECIMAL.",
                "required": [
                    "report_date",
                    "clicks_total"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of the ADMIN daily-clicks report (GET /admin/v1/reports/clicks).\nCarries `publisher_cpc_sum` (the unshared gross the sponsor paid) — admin-only.\nThe sponsor and publisher clicks reports have their own row shapes that omit it\n(ReportSponsorClicksDailyRow / ReportPublisherClicksDailyRow).\n\nBacked by JuJu\\Common\\Libraries\\Reports\\ClicksReport.",
                        "type": "string",
                        "format": "date"
                    },
                    "publisher_account_id": {
                        "description": "Present only when group_by includes account.",
                        "type": "integer"
                    },
                    "publisher_account_name": {
                        "description": "Present only when group_by includes account.",
                        "type": "string",
                        "nullable": true
                    },
                    "publisher_id": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "integer"
                    },
                    "publisher_name": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "string",
                        "nullable": true
                    },
                    "job_provider_id": {
                        "description": "Present only when group_by includes provider.",
                        "type": "integer"
                    },
                    "job_provider_name": {
                        "description": "Present only when group_by includes provider.",
                        "type": "string",
                        "nullable": true
                    },
                    "clicks_total": {
                        "description": "Every click, including bot + duplicate.",
                        "type": "integer"
                    },
                    "clicks_billable": {
                        "description": "Excludes bot + duplicate.",
                        "type": "integer"
                    },
                    "clicks_bot": {
                        "type": "integer"
                    },
                    "clicks_duplicate": {
                        "type": "integer"
                    },
                    "serves_total": {
                        "description": "Server-side \"we sent this job\" count.",
                        "type": "integer"
                    },
                    "impressions_total": {
                        "description": "Client-confirmed viewport count.",
                        "type": "integer"
                    },
                    "publisher_cpc_sum": {
                        "description": "Sum of cpc_at_click for billable clicks. Publisher earnings = this × cpc_share.",
                        "type": "string",
                        "example": "4211.5500"
                    }
                },
                "type": "object"
            },
            "ReportEarningsDailyRow": {
                "title": "Daily Earnings Report Row",
                "description": "One day's share-adjusted earnings for a publisher scope. Money as string DECIMAL.",
                "required": [
                    "report_date",
                    "clicks_total",
                    "earnings"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of a daily-earnings report. Publisher-oriented — earnings\nreflect cpc_share × publisher_cpc_sum, computed at query time using\neach account's CURRENT cpc_share.\n\nBacked by JuJu\\Common\\Libraries\\Reports\\EarningsReport::fetch_daily.",
                        "type": "string",
                        "format": "date"
                    },
                    "publisher_account_id": {
                        "description": "Present only when group_by includes account.",
                        "type": "integer"
                    },
                    "publisher_account_name": {
                        "description": "Present only when group_by includes account.",
                        "type": "string",
                        "nullable": true
                    },
                    "publisher_id": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "integer"
                    },
                    "publisher_name": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "string",
                        "nullable": true
                    },
                    "job_provider_id": {
                        "description": "Present only when group_by includes provider.",
                        "type": "integer"
                    },
                    "job_provider_name": {
                        "description": "Present only when group_by includes provider.",
                        "type": "string",
                        "nullable": true
                    },
                    "clicks_total": {
                        "type": "integer"
                    },
                    "clicks_billable": {
                        "type": "integer"
                    },
                    "earnings": {
                        "description": "publisher_cpc_sum × cpc_share.",
                        "type": "string",
                        "example": "2948.09"
                    }
                },
                "type": "object"
            },
            "ReportOffersDailyRow": {
                "title": "Daily Offer Report Row",
                "description": "One day's offer-funnel aggregates. Money as string DECIMAL. offer_id / offer_partner_id appear when grouped by offer / partner.",
                "required": [
                    "report_date",
                    "impressions_total",
                    "clicks_total",
                    "conversions_total",
                    "payout_sum"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of a daily offer-funnel report — impressions → clicks → conversions\n→ payout, aggregated from offer.offer_daily_rollup.\n\nBacked by JuJu\\Common\\Libraries\\Reports\\OffersReport. When grouped by offer or\npartner, the row also carries `offer_id` / `offer_partner_id`.",
                        "type": "string",
                        "format": "date"
                    },
                    "offer_id": {
                        "description": "Present when grouped by offer.",
                        "type": "integer"
                    },
                    "offer_name": {
                        "description": "Present when grouped by offer; null if the offer was deleted.",
                        "type": "string",
                        "nullable": true
                    },
                    "offer_partner_id": {
                        "description": "Present when grouped by partner.",
                        "type": "integer"
                    },
                    "offer_partner_name": {
                        "description": "Present when grouped by partner; null if the partner was deleted.",
                        "type": "string",
                        "nullable": true
                    },
                    "impressions_total": {
                        "type": "integer"
                    },
                    "clicks_total": {
                        "type": "integer"
                    },
                    "conversions_total": {
                        "type": "integer"
                    },
                    "payout_sum": {
                        "description": "SUM(payout_at_submit) for accepted + delivered conversions.",
                        "type": "string",
                        "example": "1183.4400"
                    }
                },
                "type": "object"
            },
            "ReportPublisherClicksDailyRow": {
                "title": "Publisher Daily Clicks Report Row",
                "description": "One day's click aggregates for the publisher's own clicks, with net (share-adjusted) earnings. All money as string DECIMAL.",
                "required": [
                    "report_date",
                    "clicks_total"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of the PUBLISHER clicks report (GET /publisher/v1/reports/clicks),\nbacked by JuJu\\Common\\Libraries\\Reports\\PublisherClicksReport.\n\nDistinct from ReportClicksDailyRow (the admin shape) on purpose: a publisher\nmust NEVER see `publisher_cpc_sum` (the unshared gross the sponsor paid — it\nreveals JuJu's margin). This row carries `earnings` instead: the snapshotted,\nshare-adjusted amount the publisher actually keeps. id + name columns appear\nonly when the matching group_by dimension is requested.",
                        "type": "string",
                        "format": "date"
                    },
                    "publisher_account_id": {
                        "description": "Present only when group_by includes account.",
                        "type": "integer"
                    },
                    "publisher_account_name": {
                        "description": "Present only when group_by includes account.",
                        "type": "string",
                        "nullable": true
                    },
                    "publisher_id": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "integer"
                    },
                    "publisher_name": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "string",
                        "nullable": true
                    },
                    "clicks_total": {
                        "description": "Every click, including bot + duplicate.",
                        "type": "integer"
                    },
                    "clicks_billable": {
                        "description": "Excludes bot + duplicate.",
                        "type": "integer"
                    },
                    "clicks_bot": {
                        "type": "integer"
                    },
                    "clicks_duplicate": {
                        "type": "integer"
                    },
                    "serves_total": {
                        "description": "Server-side \"we sent this job\" count.",
                        "type": "integer"
                    },
                    "impressions_total": {
                        "description": "Client-confirmed viewport count.",
                        "type": "integer"
                    },
                    "earnings": {
                        "description": "Net earnings the publisher keeps for billable clicks — snapshotted cpc_at_click × cpc_share at roll time. (The unshared gross is deliberately not exposed to publishers.)",
                        "type": "string",
                        "example": "1473.9000"
                    }
                },
                "type": "object"
            },
            "ReportPublisherEarningsDailyRow": {
                "title": "Publisher Daily Earnings Report Row",
                "description": "One day's share-adjusted earnings for the publisher's own scope. Money as string DECIMAL.",
                "required": [
                    "report_date",
                    "clicks_total",
                    "earnings"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of the PUBLISHER earnings report (GET /publisher/v1/reports/earnings),\nbacked by JuJu\\Common\\Libraries\\Reports\\PublisherEarningsReport.\n\nDistinct from ReportEarningsDailyRow (the admin shape) on purpose: the publisher\nsurface does NOT expose the job provider — no job_provider_id / job_provider_name,\nand no provider group_by. `earnings` is the snapshotted, share-adjusted amount the\npublisher keeps. id + name columns appear only when the matching group_by is requested.",
                        "type": "string",
                        "format": "date"
                    },
                    "publisher_account_id": {
                        "description": "Present only when group_by includes account.",
                        "type": "integer"
                    },
                    "publisher_account_name": {
                        "description": "Present only when group_by includes account.",
                        "type": "string",
                        "nullable": true
                    },
                    "publisher_id": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "integer"
                    },
                    "publisher_name": {
                        "description": "Present only when group_by includes publisher.",
                        "type": "string",
                        "nullable": true
                    },
                    "clicks_total": {
                        "type": "integer"
                    },
                    "clicks_billable": {
                        "type": "integer"
                    },
                    "earnings": {
                        "description": "Net earnings the publisher keeps — publisher_earnings snapshotted (cpc_at_click × cpc_share) at roll time.",
                        "type": "string",
                        "example": "2948.09"
                    }
                },
                "type": "object"
            },
            "ReportSpendDailyRow": {
                "title": "Daily Spend Report Row",
                "description": "One day's spend aggregates for a sponsor scope. Money as string DECIMAL.",
                "required": [
                    "report_date",
                    "clicks_total",
                    "spend"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of a daily-spend report. Sponsor-oriented — spend is what the\nsponsor paid, aggregated from click_sponsor_daily_rollup.\n\nBacked by JuJu\\Common\\Libraries\\Reports\\SpendReport::fetch_daily.",
                        "type": "string",
                        "format": "date"
                    },
                    "campaign_id": {
                        "description": "Present only when group_by includes campaign.",
                        "type": "integer"
                    },
                    "campaign_name": {
                        "description": "Present only when group_by includes campaign.",
                        "type": "string",
                        "nullable": true
                    },
                    "job_provider_id": {
                        "description": "Present only when group_by includes provider.",
                        "type": "integer"
                    },
                    "job_provider_name": {
                        "description": "Present only when group_by includes provider.",
                        "type": "string",
                        "nullable": true
                    },
                    "segment_id": {
                        "description": "Present only when group_by includes segment.",
                        "type": "integer"
                    },
                    "segment_name": {
                        "description": "Present only when group_by includes segment.",
                        "type": "string",
                        "nullable": true
                    },
                    "job_partner_id": {
                        "description": "Present only when group_by includes sponsor.",
                        "type": "integer"
                    },
                    "job_partner_name": {
                        "description": "Present only when group_by includes sponsor.",
                        "type": "string",
                        "nullable": true
                    },
                    "clicks_total": {
                        "type": "integer"
                    },
                    "spend": {
                        "description": "Sum of cpc_at_click for billable clicks (bot + duplicate excluded).",
                        "type": "string",
                        "example": "4211.5500"
                    },
                    "serves_total": {
                        "type": "integer"
                    },
                    "impressions_total": {
                        "type": "integer"
                    }
                },
                "type": "object"
            },
            "ReportSponsorClicksDailyRow": {
                "title": "Sponsor Daily Clicks Report Row",
                "description": "One day's click aggregates for the sponsor's own inventory. campaign_id / job_provider_id / segment_id are present only when the matching group_by dimension is requested.",
                "required": [
                    "report_date",
                    "clicks_total"
                ],
                "properties": {
                    "report_date": {
                        "description": "One row of the SPONSOR clicks report (GET /sponsor/v1/reports/clicks),\nbacked by JuJu\\Common\\Libraries\\Reports\\SponsorClicksReport on the sponsor\nclick rollup.\n\nDistinct from ReportClicksDailyRow (the admin/publisher shape) on purpose:\nthe sponsor report is sourced from the sponsor rollup, which has no publisher\ncolumns — so there is deliberately NO publisher_cpc_sum, publisher_account_id,\nor publisher_id here. Dimension columns (campaign_id, job_provider_id,\nsegment_id) appear only when requested via group_by.",
                        "type": "string",
                        "format": "date"
                    },
                    "campaign_id": {
                        "description": "Present only when group_by includes campaign.",
                        "type": "integer"
                    },
                    "campaign_name": {
                        "description": "Present only when group_by includes campaign.",
                        "type": "string",
                        "nullable": true
                    },
                    "job_provider_id": {
                        "description": "Present only when group_by includes provider.",
                        "type": "integer"
                    },
                    "job_provider_name": {
                        "description": "Present only when group_by includes provider.",
                        "type": "string",
                        "nullable": true
                    },
                    "segment_id": {
                        "description": "Present only when group_by includes segment.",
                        "type": "integer"
                    },
                    "segment_name": {
                        "description": "Present only when group_by includes segment.",
                        "type": "string",
                        "nullable": true
                    },
                    "clicks_total": {
                        "description": "Every click, including bot + duplicate.",
                        "type": "integer"
                    },
                    "clicks_billable": {
                        "description": "Excludes bot + duplicate.",
                        "type": "integer"
                    },
                    "clicks_bot": {
                        "type": "integer"
                    },
                    "clicks_duplicate": {
                        "type": "integer"
                    },
                    "serves_total": {
                        "description": "Server-side \"we sent this job\" count.",
                        "type": "integer"
                    },
                    "impressions_total": {
                        "description": "Client-confirmed viewport count.",
                        "type": "integer"
                    }
                },
                "type": "object"
            }
        },
        "securitySchemes": {
            "sponsorCallbackKey": {
                "type": "http",
                "description": "Per-sponsor conversion-callback key (Bearer). Issued in the admin console per sponsor; one key covers all that sponsor's providers; used ONLY on POST /api/v1/conversions.",
                "scheme": "bearer"
            },
            "publisherApiKey": {
                "type": "http",
                "description": "Publisher API key (Bearer), issued per publisher.publisher_account in the admin console. Required on the api.juju.com job + feed endpoints. Presented as `Authorization: Bearer <key>`; `X-API-Key` is NOT accepted. A missing OR invalid key both return 401.",
                "scheme": "bearer"
            }
        }
    },
    "tags": [
        {
            "name": "Auth",
            "description": "Login and logout for the admin/sponsor/publisher portals."
        },
        {
            "name": "Me",
            "description": "Current-session identity lookup on the admin surface."
        },
        {
            "name": "Account",
            "description": "Sponsor / publisher portal self-view — profile + linked org + earnings summary."
        },
        {
            "name": "Dashboard",
            "description": "Aggregate for the admin landing screen."
        },
        {
            "name": "Sponsor",
            "description": "sponsor.job_partner — the top-level sponsor / job-partner orgs."
        },
        {
            "name": "Provider",
            "description": "sponsor.job_provider — feed sources under each sponsor."
        },
        {
            "name": "Feed Run",
            "description": "jobs.run_info — dispatch history and worker telemetry."
        },
        {
            "name": "Campaign",
            "description": "sponsor.job_provider_campaign — targeting + budget, incl. nested segment ops."
        },
        {
            "name": "Segment",
            "description": "sponsor.job_provider_campaign_segment — standalone segment CRUD."
        },
        {
            "name": "Publisher",
            "description": "publisher.publisher — publisher orgs."
        },
        {
            "name": "Publisher Account",
            "description": "publisher.publisher_account — API-key credentials per publisher."
        },
        {
            "name": "User",
            "description": "juju.user — consumer accounts (support / ops surface)."
        },
        {
            "name": "Admin User",
            "description": "admin.admin_user — internal staff logins."
        },
        {
            "name": "Sponsor Login",
            "description": "sponsor.sponsor_login — sponsor-portal human logins."
        },
        {
            "name": "Publisher Login",
            "description": "publisher.publisher_login — publisher-portal human logins."
        },
        {
            "name": "Report",
            "description": "Aggregated telemetry (clicks, spend, earnings, API usage) over the daily rollup tables."
        },
        {
            "name": "Offer Partner",
            "description": "offer.offer_partner — partner orgs that own offers."
        },
        {
            "name": "Offer",
            "description": "offer.offer — the main offer entity (targeting, priority, compliance flags)."
        },
        {
            "name": "Offer Schedule",
            "description": "offer.offer_schedule — per-day time-of-day windows in the offer's timezone."
        },
        {
            "name": "Offer Zipcode",
            "description": "offer.offer_zipcode — per-offer zipcode allowlist. No rows = \"all US eligible\"."
        },
        {
            "name": "Offer List",
            "description": "offer.offer_list + junctions — named bundles routed to sponsors + publishers by the serving-layer matcher."
        },
        {
            "name": "Conversions",
            "description": "Inbound CPA conversion callbacks — sponsors post back confirmed applications on jobs.click_conversion."
        },
        {
            "name": "Invoice",
            "description": "billing.invoice — sponsor invoices (admin manage; sponsor portal self-view)."
        },
        {
            "name": "Payment",
            "description": "billing.payment — sponsor payments received (card charge or recorded remittance)."
        },
        {
            "name": "Payout",
            "description": "billing.payout — publisher payouts (admin manage; publisher portal self-view)."
        },
        {
            "name": "Adjustment",
            "description": "billing.adjustment — operator credits/debits against a sponsor or publisher."
        },
        {
            "name": "Billing Profile",
            "description": "billing.sponsor_billing_profile + payout_profile — billing terms, cadence, payout config."
        },
        {
            "name": "Notification",
            "description": "admin.notification — the shared admin alert inbox (open → acknowledged → resolved/dismissed)."
        },
        {
            "name": "Consent",
            "description": "juju.consent_document — versioned legal disclosures (Terms of Service, opt-in copy). Immutable; publish a new version to edit."
        },
        {
            "name": "Lookup",
            "description": "Form-population data (dropdowns, enum values)."
        },
        {
            "name": "System",
            "description": "Platform health probes and internal telemetry."
        },
        {
            "name": "Health",
            "description": "Unauthenticated liveness endpoints for load balancers."
        },
        {
            "name": "Clicks",
            "description": "Clicks"
        },
        {
            "name": "Feeds",
            "description": "Feeds"
        },
        {
            "name": "Jobs",
            "description": "Jobs"
        },
        {
            "name": "Monitoring",
            "description": "Monitoring"
        },
        {
            "name": "Compliance",
            "description": "Compliance"
        },
        {
            "name": "Site",
            "description": "Site"
        },
        {
            "name": "Tracking",
            "description": "Tracking"
        },
        {
            "name": "Users",
            "description": "Users"
        },
        {
            "name": "Profile",
            "description": "Profile"
        },
        {
            "name": "SavedJobs",
            "description": "SavedJobs"
        },
        {
            "name": "SavedSearches",
            "description": "SavedSearches"
        },
        {
            "name": "SearchHistory",
            "description": "SearchHistory"
        }
    ]
}