{
  "openapi": "3.1.0",
  "info": {
    "title": "Zoekworden Campaign API",
    "version": "v1",
    "description": "REST API for AI assistants to read keyword trends, campaign performance and recommendations, and to create Google Ads campaigns in a safe, human-approved workflow. Campaigns are always created paused with a budget ceiling; a human enables them in the Google Ads UI."
  },
  "servers": [
    {
      "url": "https://zoekworden.nl/api"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    },
    "schemas": {
      "CampaignCreateRequest": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "title": "CampaignCreateRequest",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "daily_budget_eur",
          "budget_cap_eur",
          "keywords"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 3,
            "maxLength": 255
          },
          "daily_budget_eur": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 100000,
            "description": "Daily budget in EUR. Must be <= budget_cap_eur."
          },
          "budget_cap_eur": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 100000,
            "description": "Hard ceiling set by the account owner, in EUR."
          },
          "target_country": {
            "type": "string",
            "pattern": "^[a-zA-Z]{2}$",
            "default": "nl",
            "description": "ISO-3166 alpha-2 country code."
          },
          "keywords": {
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 80
            }
          },
          "final_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 500,
            "description": "Landing page URL for the ads."
          }
        }
      }
    }
  },
  "security": [
    {
      "bearer": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "paths": {
    "/v1/me": {
      "get": {
        "summary": "Identify the key and its scope."
      }
    },
    "/v1/keywords/trends": {
      "get": {
        "summary": "Keyword metrics and daily search-volume series.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "nl"
            }
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 30,
              "maximum": 90
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ]
      }
    },
    "/v1/campaigns": {
      "get": {
        "summary": "List the key owner's campaigns."
      },
      "post": {
        "summary": "Create a PAUSED campaign (write scope; Idempotency-Key header required).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignCreateRequest"
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{id}": {
      "get": {
        "summary": "Campaign detail with daily ROAS/ACOS series."
      }
    },
    "/v1/usage": {
      "get": {
        "summary": "API usage and remaining quota."
      }
    },
    "/v1/recommendations": {
      "get": {
        "summary": "Current optimisation recommendations."
      }
    }
  }
}