Documentation

Complete guide to context building for NotionPyx expressions.

Notion Integration

API Version

Notionpyx uses Notion API version 2026-03-11. This version is centralized in the module core/notion/notion_client_wrapper.py.

Webhook Functioning

Notion webhooks allow receiving real-time notifications when page content changes. The endpoint /webhooks/notion only accepts POST requests.

  • Hook validation via UUID
  • HMAC-SHA256 signature verification
  • Quick response (<200ms) to avoid Notion timeouts
  • Logging of all events

np_ai Functioning

The np_ai property in a Notion page contains the local prompt. The pyx_ai engine:

  • Triggered by Notion webhook or Smart Reminder
  • Reads page content via blocks.children.list
  • Generates content via AI
  • Replaces content via blocks.children.append after erase_content
  • Adds a comment with metrics (model, tokens, duration)

Notion Limitations

  • Markdown not supported: Notion does not support free markdown. Content must be sent via Blocks API.
  • Blocks required: All content must be formatted as blocks (heading_1, heading_2, paragraph, bulleted_list_item, etc.)
  • Rate limiting: Notion API imposes limits (3 req/s per token)
  • Payload size: Large requests may be rejected

AI Comments

After each pyx_ai execution, a comment is added to the page with:

  • AI model used (e.g., gpt-4.1-mini)
  • Execution duration in milliseconds
  • Token count (prompt/completion/total)

Logs and Metrics

Notionpyx records:

  • All Notion API calls (request_id, status)
  • 429 errors (rate limiting) with retry
  • Metrics per job (duration, tokens, success/failure)
  • Webhook events received

Introduction

The Context Builder allows fetching external data (HTTP API) and custom variables to produce a global context usable in your expression rules.

All loaded values are normalized and exposed as variables that you can then reference in Notionpyx expressions.

Context Concept

A context is a named data source. Each context can call an API, return JSON, then inject this JSON into the global context under a prefix.

Context name: meteo_paris
JSON received: {"temperature": 18, "condition": "clear"}
Available variables:
- {meteo_paris.temperature}
- {meteo_paris.condition}

Creating an HTTP Context

GET / POST Methods

Choose GET for simple read calls. Use POST when the API expects a JSON body.

Headers

Add your headers as key/value pairs. For the Notion API, URLs starting with https://api.notion.com/v1/ trigger automatic header injection.

JSON Body

The body is used for POST requests. You can include configuration variables.

{
  "filter": {
    "property": "Status",
    "select": {"equals": "Open"}
  }
}

Context Loading (Load)

The Load button executes the HTTP call and displays two outputs:

  • Raw JSON received from the API,
  • Flattened lines to see directly usable variables.

JSON Structure

JSON can be nested. Notionpyx transforms it into flat paths.

Source JSON:
{
  "time": {"current_hour": 14},
  "location": {"city": "Paris"}
}

Flattened variables:
- {meteo_paris.time.current_hour}
- {meteo_paris.location.city}

Flattened Variables

These flattened variables are the ones to use in your expressions and conditions.

Using Variables in Expressions

Context values are used with the {variable} syntax.

Allowed string operations (examples):

{place_city_name}.strip()
{place_city_name}.lower()
{place_city_name}.replace(' ','_')
{place_city_name}.split(',')[0]
regex({place_city_name}, r'[A-Z]+')

Custom Context Variables

Add static or computed key/value pairs to enrich the Global Context without HTTP calls.

Key: timezone
Value: Europe/Paris
=> Usable via {timezone}

Logical Expressions (and / or / ternary)

# and / or
({meteo_paris.temperature} < 5) and ({meteo_paris.condition} != 'snow')
({timezone} == 'Europe/Paris') or ({timezone} == 'Europe/Brussels')

# ternary
'umbrella' if {meteo_paris.condition} == 'rain' else 'sunglasses'

Complete Examples

Weather Example

Context name: meteo_paris
Method: GET
URL: https://api.weather.example/current?city=Paris

Expression:
'cold_alert' if {meteo_paris.temperature} < 3 else 'ok'

Notion API Example

Context name: notion_tasks
Method: POST
URL: https://api.notion.com/v1/data_sources/<data_source_id>/query
Body:
{
  "filter": {
    "property": "Done",
    "checkbox": {"equals": false}
  }
}

Possible variables after load:
- {notion_tasks.results[0].id}
- {notion_tasks.results[0].properties.Name.title[0].plain_text}

Conditional Expression Example

Custom variable: user_lang = en

Expression:
'Bonjour' if {user_lang} == 'fr' else 'Hello'

Best Practices

  • Use explicit context names (meteo_paris, notion_tasks).
  • Test each context with Load before using it in expressions.
  • Avoid ambiguous keys in custom variables.
  • Keep expressions readable and split complex logic into intermediate variables.

Additional Documentation