Notion API Updates April 2026: Views API, Smart Filters, and Migration Guide

Matthew Diakonov··10 min read

Notion API Updates April 2026: Views API, Smart Filters, and Migration Guide

The Notion API version 2026-04-01, released on April 7, is the largest API update Notion has shipped in 2026. It introduces the Views API (eight new endpoints), smart filter operators, new block types, and several infrastructure changes that affect rate limiting and pagination. This post walks through every change, with code examples, comparison tables, and a step-by-step migration checklist.

What Changed in the April 2026 Notion API Release

| Category | Change | Impact | |---|---|---| | Views API | 8 new endpoints for CRUD operations on database views | High - enables programmatic view management | | Smart Filters | Relative date references (this_week, past_month, etc.) | Medium - simplifies date-based queries | | Smart Filters | "me" operator for people properties | Medium - removes need to pass user IDs | | Webhooks | Top-level event_type field added to payloads | Low - convenience; old parsing still works | | Rate Limits | Header format changed from X-RateLimit-* to RateLimit-* | High - breaks existing retry logic | | Rate Limits | RateLimit-Reset now returns seconds delta, not Unix timestamp | High - breaks existing retry logic | | Pagination | Cursor format changed to base64-encoded strings | Medium - stored cursors must be invalidated | | Block Types | Toggle heading blocks (heading_1, heading_2, heading_3 with is_toggleable) | Low - new capability | | Block Types | Synced block copy support via API | Low - new capability | | Filters | is_archived filter for database queries | Low - new capability |

Views API: The Headline Feature

Before April 2026, database views were only configurable through the Notion UI. The new Views API lets integrations create, read, update, and delete views programmatically.

All 8 Views API Endpoints

| Endpoint | Method | What It Does | |---|---|---| | /v1/databases/{db_id}/views | GET | List all views on a database | | /v1/databases/{db_id}/views | POST | Create a new view | | /v1/views/{view_id} | GET | Retrieve a single view | | /v1/views/{view_id} | PATCH | Update view configuration | | /v1/views/{view_id} | DELETE | Delete a view | | /v1/views/{view_id}/duplicate | POST | Clone an existing view | | /v1/views/{view_id}/properties | PATCH | Configure visible columns and order | | /v1/views/{view_id}/query | POST | Query data through a view's filters and sorts |

Five view types are supported: table, board, timeline, calendar, and list. Gallery views are not yet available through the API.

Creating a Board View

curl -X POST "https://api.notion.com/v1/databases/$DB_ID/views" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2026-04-01" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "board",
    "title": "Sprint Board",
    "group_by": {
      "property": "Status"
    },
    "filter": {
      "property": "Sprint",
      "select": { "equals": "Sprint 14" }
    },
    "sorts": [
      { "property": "Priority", "direction": "ascending" }
    ]
  }'

The response includes the view_id you can use for subsequent operations.

Querying Through a View

The /v1/views/{view_id}/query endpoint is particularly useful for integrations that need to mirror what a user sees in the Notion UI. Instead of rebuilding the view's filter and sort logic in your code, you query through the view directly:

curl -X POST "https://api.notion.com/v1/views/$VIEW_ID/query" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2026-04-01" \
  -H "Content-Type: application/json" \
  -d '{
    "page_size": 50
  }'

The response uses the same format as /v1/databases/{id}/query but applies the view's filters, sorts, and grouping automatically.

Views API Request FlowYour IntegrationNotion-Version: 2026-04-01RESTNotion APIVersion RouterDatabase EndpointsViews Endpoints (NEW)8 View OperationsGET /databases/id/viewsPOST /databases/id/viewsGET /views/idPATCH /views/idDELETE /views/idPOST /views/id/duplicateSupported View TypesTableBoardTimelineCalendarListGallery(not yet supported)

Smart Filter Operators

April 2026 introduces two new filter operators that simplify common query patterns.

Relative Date References

Instead of computing timestamps in your integration, you can now use named date references:

{
  "filter": {
    "property": "Due Date",
    "date": { "this_week": {} }
  }
}

All available relative date values:

| Value | Resolves To | |---|---| | past_week | 7 days before the current moment | | past_month | 30 days before the current moment | | this_week | Monday through Sunday of the current week | | next_week | Monday through Sunday of the following week | | next_month | First through last day of the following month |

These resolve server-side at query time, so your integration does not need to handle timezone calculations.

The "me" Operator

For people properties, the new "me" value resolves to the user associated with the API token:

{
  "filter": {
    "property": "Assigned To",
    "people": { "contains": "me" }
  }
}

This is useful for building views scoped to the current user without needing to look up their user ID first. It works with both integration tokens and OAuth tokens.

Webhook Improvements

The April API version adds a top-level event_type field to webhook payloads. In the March release (2026-03-01), you had to inspect data.object and data.action to determine the event type. The new format looks like this:

{
  "event_id": "evt_abc123",
  "event_type": "page.updated",
  "timestamp": "2026-04-10T14:30:00.000Z",
  "data": {
    "object": "page",
    "action": "updated",
    "page_id": "page_xyz",
    "changes": {
      "properties": {
        "Status": {
          "old": { "status": { "name": "To Do" } },
          "new": { "status": { "name": "In Progress" } }
        }
      }
    }
  }
}

The data object structure is unchanged from March, so existing webhook handlers continue to work. The event_type field is additive.

Rate Limit and Pagination Changes

These are the changes most likely to break existing integrations.

Rate Limit Header Migration

The April API version switches from the X-RateLimit-* prefix to RateLimit-*, following RFC 9110:

| Old Header (deprecated) | New Header | Notes | |---|---|---| | X-RateLimit-Limit | RateLimit-Limit | Requests allowed per window | | X-RateLimit-Remaining | RateLimit-Remaining | Requests remaining in window | | X-RateLimit-Reset | RateLimit-Reset | Changed from Unix timestamp to seconds delta |

The old X-RateLimit-* headers are still returned alongside the new ones, but they are deprecated and will be removed in a future API version.

The RateLimit-Reset change is the most impactful. If your retry logic parses this header, it needs to be updated:

# Before (Unix timestamp)
reset_at = int(response.headers["X-RateLimit-Reset"])
wait_seconds = reset_at - time.time()

# After (seconds delta)
wait_seconds = int(response.headers["RateLimit-Reset"])

Pagination Cursor Format

Pagination cursors changed from UUID-like strings to opaque base64-encoded values. Cursors from the old format still work when passed to the new API version, but cursors generated by the new API version do not work with older API versions.

If your integration stores cursors between requests (for example, to resume paginated syncs), invalidate all stored cursors when upgrading to 2026-04-01.

New Block Types

Two block type improvements arrived in April:

Toggle heading blocks: The heading_1, heading_2, and heading_3 block types now support an is_toggleable property. When set to true, the heading acts as a toggle in the Notion UI and can contain child blocks:

{
  "type": "heading_2",
  "heading_2": {
    "rich_text": [{ "text": { "content": "FAQ Section" } }],
    "is_toggleable": true,
    "children": [
      {
        "type": "paragraph",
        "paragraph": {
          "rich_text": [{ "text": { "content": "Answer content here." } }]
        }
      }
    ]
  }
}

Synced block copy: You can now duplicate synced blocks through the API. Previously, creating a copy of a synced block required the Notion UI.

Migration Checklist: Upgrading to 2026-04-01

If you are upgrading from 2026-03-01 or earlier, work through this list:

  1. Rate limit headers: Update retry logic to parse RateLimit-* instead of X-RateLimit-*
  2. Reset value: Change RateLimit-Reset parsing from Unix timestamp to seconds delta
  3. Pagination cursors: Invalidate any stored cursors before switching the API version header
  4. Webhook parsing (optional): Add event_type reading alongside existing data.action parsing
  5. Test with version pinning: Set Notion-Version: 2026-04-01 on one endpoint at a time to catch issues incrementally

Warning

Do not upgrade your Notion-Version header during an active paginated sync. Finish or reset the sync first. Cursors from the new format are not backward-compatible with older API versions.

Before and After: April 2026 API Comparison

| Feature | Before April 2026 | After April 2026 | |---|---|---| | Database views | UI only | 8 API endpoints | | Date filters | Absolute timestamps required | Relative references (this_week, etc.) | | People filters | User ID required | "me" operator available | | Webhook event routing | Inspect data.object + data.action | Read event_type at top level | | Rate limit headers | X-RateLimit-* | RateLimit-* (RFC 9110) | | Rate limit reset | Unix timestamp | Seconds delta | | Pagination cursors | UUID format | Base64 opaque strings | | Toggle headings | Not available via API | is_toggleable property | | Synced block copy | UI only | API supported |

Related Reading

For a broader timeline of all Notion API changes in 2026 (including the February bulk operations and March webhooks releases), see Notion API Updates 2026: Every Major Change So Far. For a detailed look at webhook architecture and rate limiting strategies, see Notion API Rate Limits: Polling vs Webhook Comparison.

Fazm is an open source macOS AI agent. Open source on GitHub.

Related Posts