Added

Ads API v3 is generally available

Ads API v3 is ready for production. If you use v2, migrate to v3 by March 31, 2027.


A practical comparison of the Nextdoor Ads API v2 and v3 contracts.

Nextdoor Ads API v3 keeps the same core objects: advertisers, campaigns, ad groups, ads, creatives, media, audiences, and reports. It standardizes routes, methods, pagination, and request schemas:

  • URLs identify the advertiser and resource.
  • HTTP methods describe the operation.
  • Lists use the same cursor pattern.
  • Request bodies use typed, resource-specific schemas.

If you already use v2, the biggest change is not the data model. It is how you build each request.

This changelog covers the supported Nextdoor Ads API v3 developer contract. Use the published API reference for the complete list of available resources and fields.

In this doc

The Nextdoor v3 contract, at a glance

Areav2v3What changes for you
Base path/v2/api/.../api/v3/...Update the path, then convert the route, not just the prefix.
Route styleEntity/action routes such as /campaign/createAdvertiser-scoped resources such as /advertisers/{advertiserId}/campaignsPut scope and object identity in the URL.
HTTP methodsPOST is used for many mutationsGET reads, POST creates, PUT updates, DELETE archivesReplace action-style POST calls with standard methods.
Advertiser scopeOften in the JSON body as advertiser_idIn the URL as {advertiserId}Remove the duplicate advertiser ID from mutation bodies.
Object IDsOften id in the body or an action URLTyped path parameters such as {campaignId}Move the object ID into the item URL.
List paginationLegacy, endpoint-specific inputsCursor pagination with pageSize, cursor, and pageInfoFollow pageInfo.endCursor until it is absent.
Query parametersLegacy naming and placementcamelCase: pageSize, includeArchived, startTime, endTimeUpdate query builders and serializers.
JSON bodiesMixed legacy contractsnake_case fields such as campaign_id and user_statusKeep body serialization separate from query serialization.
StatusSeparate action-style POST routesPUT .../{id}/statusSend user_status to the resource’s status route.
ArchiveLegacy status/action behaviorDELETE .../{id}Treat archive as a resource operation.
Contract sourceLegacy schemas and endpoint behaviorPublished schemas, route docs, and generated OpenAPIThe published contract and API behavior stay aligned.

Resource map

The paths below include the runtime v3 prefix. Braced values are path parameters.

ResourcePublic v3 surfaceNotes
AdvertiserGET /api/v3/advertisers/{advertiserId}; GET /api/v3/advertisers/{advertiserId}/stats; POST /api/v3/advertisersCreate uses the collection route; the new advertiser ID is not sent in the body.
CampaignList, get, stats, create, update, status, archiveCollection: /api/v3/advertisers/{advertiserId}/campaigns; item: /campaigns/{campaignId}.
Ad groupList, get, stats, create, update, status, archiveCollection: /api/v3/advertisers/{advertiserId}/adgroups; item: /adgroups/{adgroupId}. Lists can filter by campaignId.
AdList, get, stats, create, update, status, archiveCollection: /api/v3/advertisers/{advertiserId}/ads; item: /ads/{adId}. Lists can filter by parentId.
CreativeList, get, stats, create, update, archiveCollection: /api/v3/advertisers/{advertiserId}/creatives; item: /creatives/{creativeId}. Creative formats follow the documented v3 creative types.
Media assetList, get, upload, archiveCollection: /api/v3/advertisers/{advertiserId}/media; item: /media/{mediaId}. The examples here cover the public image flow.
AudienceAdvertiser-scoped audience operations exposed by the documented schemaUse the documented audience fields and operations.
TargetingPublic geographic lookup resourcesThese routes return reference data; they do not mutate campaigns.
ReportingAdvertiser-scoped reports and report schedulesOne-off reports, schedules, and generated reports are modeled as resources.

Resource changes

Advertisers and scoped collections

V2 exposes many lists through entity/action routes. V3 nests collections under the advertiser:

TEXT

/api/v3/advertisers/{advertiserId}/campaigns

/api/v3/advertisers/{advertiserId}/adgroups

/api/v3/advertisers/{advertiserId}/ads

/api/v3/advertisers/{advertiserId}/creatives

That makes ownership part of the request instead of something the client has to infer from a body field or endpoint name.

Campaigns

Operationv2v3
Get oneGET /v2/api/campaign/get/{id}GET /api/v3/advertisers/{advertiserId}/campaigns/{campaignId}
StatsGET /v2/api/campaign/get/{id}/statsGET /api/v3/advertisers/{advertiserId}/campaigns/{campaignId}/stats?startTime=YYYY-MM-DD&endTime=YYYY-MM-DD
CreatePOST /v2/api/campaign/createPOST /api/v3/advertisers/{advertiserId}/campaigns
UpdatePOST /v2/api/campaign/updatePUT /api/v3/advertisers/{advertiserId}/campaigns/{campaignId}
StatusPOST /v2/api/campaign/status/updatePUT /api/v3/advertisers/{advertiserId}/campaigns/{campaignId}/status
ArchiveLegacy action/status behaviorDELETE /api/v3/advertisers/{advertiserId}/campaigns/{campaignId}

In v3, the create body carries campaign fields such as name, objective, and optional sub_objective. advertiser_id moves into the URL. Updates use a partial body; the public implementation currently exposes campaign name updates.

Ad groups

V3 turns the ad group into a first-class advertiser-scoped resource:

  • GET /api/v3/advertisers/{advertiserId}/adgroups
  • GET /api/v3/advertisers/{advertiserId}/adgroups/{adgroupId}
  • GET /api/v3/advertisers/{advertiserId}/adgroups/{adgroupId}/stats
  • POST /api/v3/advertisers/{advertiserId}/adgroups
  • PUT /api/v3/advertisers/{advertiserId}/adgroups/{adgroupId}
  • PUT /api/v3/advertisers/{advertiserId}/adgroups/{adgroupId}/status
  • DELETE /api/v3/advertisers/{advertiserId}/adgroups/{adgroupId}

The create body keeps the parent relationship explicit with campaign_id. It also carries the ad group’s name, placements, bid, budget, schedule, frequency caps, targeting, and supported status fields. Updates are partial; send the fields you want to change instead of rebuilding the entire object.

Ads

Operationv2v3
ListGET /v2/api/ad/listGET /api/v3/advertisers/{advertiserId}/ads
Get oneGET /v2/api/ad/get/{id}GET /api/v3/advertisers/{advertiserId}/ads/{adId}
StatsGET /v2/api/ad/get/{id}/statsGET /api/v3/advertisers/{advertiserId}/ads/{adId}/stats?startTime=YYYY-MM-DD&endTime=YYYY-MM-DD
CreatePOST /v2/api/ad/createPOST /api/v3/advertisers/{advertiserId}/ads
UpdatePOST /v2/api/ad/updatePUT /api/v3/advertisers/{advertiserId}/ads/{adId}
StatusPOST /v2/api/ad/status/updatePUT /api/v3/advertisers/{advertiserId}/ads/{adId}/status
ArchiveLegacy action/status behaviorDELETE /api/v3/advertisers/{advertiserId}/ads/{adId}

The v3 create body contains adgroup_id, creative_id, and name. The ad ID belongs in the URL for reads, updates, status changes, and archive operations.

Creatives

V2 accepts a broad legacy input shape. V3 uses typed creative bodies, so the API can validate fields for the selected creative type instead of accepting one catch-all payload.
The public image workflow is:

  1. Upload or identify the required image assets.
  2. Create the creative at /api/v3/advertisers/{advertiserId}/creatives.
  3. Pass asset IDs such as logo_image_id and canvas_image_id in the type-specific body.
  4. Update with PUT .../creatives/{creativeId} using the matching update body.
  5. Archive with DELETE .../creatives/{creativeId}.

Media assets

V3 separates asset lifecycle from creative lifecycle:

  • GET /api/v3/advertisers/{advertiserId}/media
  • GET /api/v3/advertisers/{advertiserId}/media/{mediaId}
  • POST /api/v3/advertisers/{advertiserId}/media
  • DELETE /api/v3/advertisers/{advertiserId}/media/{mediaId}

For images, upload first, save the returned media ID, and reference it from the creative request. Archiving a media asset does not archive a creative that already references it.

Audiences and targeting

V3 makes audience reads advertiser-scoped and applies the same cursor conventions used by other collections.
Targeting lookups also move to v3 resources. Store the returned IDs and names, then pass only the targeting fields supported by the public ad group schema.

Reporting

V2 uses reporting list and scheduled-report actions. V3 models reports and schedules as advertiser-scoped resources:

  • GET /api/v3/advertisers/{advertiserId}/reports
  • GET /api/v3/advertisers/{advertiserId}/reports/schedules
  • GET /api/v3/advertisers/{advertiserId}/reports/schedules/{scheduleId}
  • GET /api/v3/advertisers/{advertiserId}/reports/schedules/{scheduleId}/generated_reports
  • POST /api/v3/advertisers/{advertiserId}/reports/schedules
  • DELETE /api/v3/advertisers/{advertiserId}/reports/schedules/{scheduleId}

Use the documented reporting schema for report types, dimensions, metrics, filters, and output formats.

Behavior that changes everywhere

Pagination

V3 lists use cursor pagination:

TEXT

?pageSize=100&cursor=<opaque-cursor>

pageSize is required and must be between 1 and 500. The response includes pageInfo.endCursor. Treat that cursor as opaque: URL-encode it, send it back unchanged, and stop when it is absent.

Archived objects

Archived objects are excluded from default lists where the resource supports archive filtering. Add includeArchived=true when you need them. An archived object is not the same as a missing object; it remains an identifiable resource.

Stats date ranges

Stats routes use startTime and endTime query parameters in YYYY-MM-DD format. The end date is inclusive. Validate returned timestamps against the advertiser timezone rather than assuming raw UTC boundaries.

Errors

V3 failures return an api_error_code and a human-readable message. Branch on the code. Use the message for diagnostics, not as a stable identifier.

Benefits of v3

  • Less guesswork: the URL tells you which advertiser and resource you are addressing.
  • More reusable clients: list, update, status, archive, and stats patterns repeat across resources.
  • Safer payloads: typed bodies catch invalid field combinations earlier.
  • Predictable large-scale reads: cursor pagination avoids offset drift.
  • Aligned contract: the published documentation, validation, and generated OpenAPI definition come from the same API contract.

Resources: Upgrade Guide · API reference · Questions? Email [email protected].