---
title: "List campaign-level negative keywords"
method: GET
path: "/v1/ads/campaigns/{campaignId}/negative-keywords"
tags: ["Ad Campaigns"]
---

# List campaign-level negative keywords

`GET /v1/ads/campaigns/{campaignId}/negative-keywords`

Returns the campaign-level negative keywords (`campaign_criterion.negative`),
distinct from the ad-group-level negatives under `GET /v1/ads/keywords`. Cached
for the quota window (not synced to Postgres), and gated by the shared Google
Ads operations budget like every other on-demand Google surface. The response
carries `cachedAt` and `stale`, set when a quota-exhausted call falls back to
the last-good copy instead of a live read.

The platform is always discovered from the campaign itself; a non-Google
campaign returns 501 rather than 404, whether or not `platform` was passed.

## Path parameters

- `campaignId` string, required

## Query parameters

- `platform` 'facebook' | 'instagram' | 'tiktok' | 'linkedin' | 'pinterest' | 'google' | 'twitter' | 'openai'

## Response `200`

Campaign-level negative keywords

- object
  - `keywords` object[]
    - `criterionId` string
    - `text` string
    - `matchType` 'exact' | 'phrase' | 'broad'
  - `cachedAt` string, date-time, nullable — When this list was fetched from Google. Null when it was never served from cache.
  - `stale` boolean — True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.

## Other responses

- `401` — Unauthorized
- `404` — Campaign not found
- `429` — Google Ads operations budget exhausted; retry later
- `501` — Only available on Google Ads campaigns

## Changes

- **2026-09-08** `d7a8fa118ef0` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/ads/campaigns/:campaignId/negative-keywords/get.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/b2325332041a?raw)
