---
title: "Notion Connector"
description: "Complete Notion integration guide for syncing databases, pages, and workspace content with Brevo via Tajo."
url: https://tajo.io/docs/connectors/custom/notion/
markdown: https://tajo.io/docs/connectors/custom/notion.md
lang: en-US
robots: noindex
---

# Notion Connector

Connector status: Planned Not built yet. Tajo does not run this connector today.

| Source field | Destination field | Sample value |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

Connect your Notion workspace to Brevo for content-driven marketing workflows, CRM database synchronization, and automated notifications through Tajo.

## Overview

| Property | Value |
| --- | --- |
| **Platform** | Notion |
| **Category** | Custom |
| **Setup Complexity** | Easy |
| **Official Integration** | No |
| **Data Synced** | Databases, Pages, Users |
| **API Type** | REST API |
| **Authentication** | Internal Integration Token / OAuth 2.0 |
| **Base URL** | `https://api.notion.com` |
| **API Version** | `2022-06-28` (via `Notion-Version` header) |

## Features

- **Database sync** - Sync Notion database entries to Brevo contacts and lists
- **CRM bridge** - Use Notion databases as a lightweight CRM, synced to Brevo
- **Content notifications** - Trigger Brevo campaigns when Notion pages are published
- **Property mapping** - Map Notion database properties to Brevo contact attributes
- **Page monitoring** - Track page updates and forward as Brevo events
- **User directory sync** - Sync Notion workspace members to Brevo contacts

## Prerequisites

Before you begin, ensure you have:

1. A Notion workspace with admin access
2. A Notion internal integration or OAuth app
3. Database pages shared with the integration
4. A Brevo account with API access
5. A Tajo account with an active subscription

## Authentication

Notion supports two authentication methods.

### Option 1: Internal Integration (Recommended for single workspace)

1. Go to [notion.so/my-integrations](https://www.notion.so/my-integrations)
2. Click **New integration**
3. Name it “Tajo Integration”
4. Select your workspace
5. Set capabilities:

```
Content Capabilities:
  Read content: ✓
  Update content: ✓
  Insert content: ✓

User Capabilities:
  Read user information: ✓
```

6. Copy the **Internal Integration Secret** (starts with `ntn_`)

Page Sharing Required

Internal integrations can only access pages and databases explicitly shared with them. Share each target database with your integration via the ”…” menu > “Connections” > select your integration.

### Option 2: OAuth 2.0 (Public integrations)

For integrations serving multiple workspaces, use the OAuth 2.0 flow:

1. Register your integration as a public integration
2. Redirect users to: `https://api.notion.com/v1/oauth/authorize?client_id=...`
3. Exchange the code for an access token at `/v1/oauth/token`

### Connecting to Tajo

```bash
tajo connectors install notion \
  --token $NOTION_TOKEN
```

## Configuration

### Basic Setup

```yaml
connectors:
  notion:
    enabled: true
    api_version: "2022-06-28"

    sync:
      databases: true
      pages: false
      users: true

    databases:
      - id: "abc123def456"
        name: "Customers"
        sync_to_list: 25
      - id: "ghi789jkl012"
        name: "Leads"
        sync_to_list: 26
```

### Field Mapping

Map Notion database properties to Brevo contact attributes:

```yaml
field_mapping:
  # Notion property -> Brevo attribute
  Name:
    type: title
    target: FIRSTNAME
  Email:
    type: email
    target: email
  Phone:
    type: phone_number
    target: SMS
  Company:
    type: rich_text
    target: COMPANY
  Status:
    type: select
    target: LEAD_STATUS
  Deal Value:
    type: number
    target: DEAL_VALUE
  Last Contact:
    type: date
    target: LAST_CONTACT_DATE
  Tags:
    type: multi_select
    target: TAGS
```

## API Endpoints

Tajo integrates with the following Notion API endpoints:

| Endpoint | Method | Purpose |
| --- | --- | --- |
| `/v1/databases/{id}/query` | POST | Query database entries |
| `/v1/databases/{id}` | GET | Retrieve database schema |
| `/v1/pages` | POST | Create a new page |
| `/v1/pages/{id}` | GET | Retrieve page properties |
| `/v1/pages/{id}` | PATCH | Update page properties |
| `/v1/blocks/{id}/children` | GET | Retrieve block children |
| `/v1/users` | GET | List all workspace users |
| `/v1/users/{id}` | GET | Retrieve a user |
| `/v1/search` | POST | Search across workspace |

## Code Examples

### Initialize Connector

```javascript
import { TajoClient } from '@tajo/sdk';

const tajo = new TajoClient({
  apiKey: process.env.TAJO_API_KEY,
  brevoApiKey: process.env.BREVO_API_KEY
});

await tajo.connectors.connect('notion', {
  token: process.env.NOTION_TOKEN
});
```

### Sync Database to Brevo

```javascript
// Sync a Notion database to a Brevo list
await tajo.connectors.sync('notion', {
  type: 'full',
  resources: ['databases'],
  databaseId: 'abc123def456',
  targetList: 25
});

const status = await tajo.connectors.status('notion');
console.log(status);
// {
//   connected: true,
//   lastSync: '2024-03-15T14:30:00Z',
//   databasesSynced: 2,
//   pagesTracked: 1450,
//   usersCount: 32
// }
```

### Query and Filter

```javascript
// Query Notion database with filters
const results = await tajo.connectors.query('notion', {
  databaseId: 'abc123def456',
  filter: {
    property: 'Status',
    select: { equals: 'Active' }
  },
  sorts: [
    { property: 'Last Contact', direction: 'descending' }
  ]
});
```

### Create Page from Brevo Event

```javascript
// Create a Notion page when a Brevo contact reaches a milestone
tajo.events.on('contact.attribute_updated', async (event) => {
  if (event.attribute === 'LIFECYCLE_STAGE' && event.value === 'customer') {
    await tajo.connectors.create('notion', {
      databaseId: 'ghi789jkl012',
      properties: {
        Name: { title: [{ text: { content: event.contact.name } }] },
        Email: { email: event.contact.email },
        'Converted Date': { date: { start: new Date().toISOString() } }
      }
    });
  }
});
```

## Rate Limits

Notion enforces rate limits per integration:

| Limit Type | Value |
| --- | --- |
| **Rate limit** | 3 requests per second per integration |
| **Burst limit** | Short bursts allowed, then throttled |
| **Page size** | 100 items max per paginated request |

Cursor-Based Pagination

Notion uses cursor-based pagination. Tajo handles this automatically, iterating through all pages using the `next_cursor` parameter until `has_more` returns `false`.

Notion returns `429 Too Many Requests` when rate limits are exceeded, with a `Retry-After` header.

## Troubleshooting

### Common Issues

| Issue | Cause | Solution |
| --- | --- | --- |
| 401 Unauthorized | Invalid or expired token | Regenerate integration token |
| 403 Forbidden | Page not shared with integration | Share page/database with integration via Connections |
| 404 Object not found | Database ID incorrect or not shared | Verify database ID and sharing settings |
| Properties missing | Schema mismatch | Re-sync database schema and update field mapping |
| Rate limit exceeded | Too many rapid requests | Reduce sync frequency or batch size |

### Debug Mode

```yaml
connectors:
  notion:
    debug: true
    log_level: verbose
    log_api_calls: true
```

### Test Connection

```bash
tajo connectors test notion
# ✓ API authentication successful
# ✓ Database access verified
# ✓ User list accessible
# ✓ Search operational
# ✓ Page creation available
```

## Best Practices

1. **Share databases explicitly** - Internal integrations only see shared content
2. **Use database queries over search** - Queries are faster and more reliable for known databases
3. **Map property types carefully** - Notion has many property types; match them to Brevo attribute types
4. **Handle pagination** - Always iterate through all cursor pages for complete data
5. **Sync incrementally** - Use `last_edited_time` filters to sync only changed entries
6. **Set up a polling schedule** - Notion does not support webhooks natively; poll at regular intervals

## Security

- **Bearer Token Authentication** - Integration secrets and OAuth tokens
- **HTTPS Only** - All API communication encrypted via TLS 1.2+
- **Scoped Access** - Integrations only access explicitly shared content
- **OAuth 2.0** - Secure authorization flow for public integrations
- **Encrypted Storage** - Tokens encrypted at rest in Tajo
- **Workspace Isolation** - Each integration is scoped to a single workspace

## Related Resources

- [Airtable Connector](https://tajo.io/docs/connectors/custom/airtable)
- [GitHub Connector](https://tajo.io/docs/connectors/custom/github)
- [Linear Connector](https://tajo.io/docs/connectors/custom/linear)
- [Brevo Contacts API](https://tajo.io/docs/contact-management)

## Open-Source Implementation Map

This section is derived from official or public repository material discovered for the Notion connector. Use it as the engineering companion to the setup guide above: it shows where the API surface lives, what implementation assets exist, and how Tajo should translate them into reliable Brevo sync behavior.

### Repository Snapshot

| Repository | Commit | Languages / formats | Files |
| --- | --- | --- | --- |
| [makenotion/notion-mcp-server](https://github.com/makenotion/notion-mcp-server) | 3bef7ad | TypeScript (19), png (5), Markdown (4), JSON (4), YAML (2), dockerignore (1) | 39 |

### Integration Shape

```mermaid
graph LR
  Source["Notion API / repository"] --> Auth["Auth and scopes"]
  Source --> Objects["Objects, events, and schemas"]
  Auth --> Tajo["Tajo connector runtime"]
  Objects --> Tajo
  Tajo --> Brevo["Brevo contacts, attributes, lists, campaigns"]
  Tajo --> Ops["Backfill, cursor, retries, logs"]
```

### What To Reuse

- Notion MCP Server
- This project implements an MCP server for the Notion API.

---

- ⚠️ Version 2.0.0 breaking changes
- **Version 2.0.0 migrates to the Notion API 2025-09-03** which introduces data sources as the primary abstraction for databases.

### Tajo Revamp Checklist

- Keep authentication setup aligned with the vendor docs and the public repository’s current API shape.
- Map primary resources into explicit Tajo sync objects with stable external IDs.
- Prefer cursor-based or updated-at incremental sync where the API exposes it; otherwise document the fallback.
- Treat webhook handlers as idempotent and replay-safe, especially for order, contact, ticket, and campaign events.
- Capture pagination, rate limits, retry headers, and partial-failure behavior in connector smoke tests.
- Keep examples small and runnable against sandbox or test-mode accounts.

### Sources

- [makenotion/notion-mcp-server](https://github.com/makenotion/notion-mcp-server)
- [Vendor documentation](https://developers.notion.com/guides/mcp/mcp)
