Working Around Notion API Limits
The Challenge of API Limitations
One of the biggest technical challenges we faced while developing NotionAiAssistant was dealing with the limitations of the Notion API, especially when creating pages with extensive Markdown-formatted content.
flowchart TD A[Markdown Content] --> B{Notion API Limitations} B -->|2000-character limit per block| C[Smart Content Splitting] B -->|Special formatting for Markdown| D[Custom Markdown Parser] B -->|100-block limit per request| E[Batch Processing] C --> F[Smart Chunking Algorithm] D --> G[Markdown to Notion Blocks Mapping] E --> H[Processing Queue with Retry] F --> I[Final Result] G --> I H --> I I --> J[Notion Page with Complete Formatted Content] style B fill:#f96,stroke:#333,stroke-width:2px style I fill:#9f6,stroke:#333,stroke-width:2px style J fill:#69f,stroke:#333,stroke-width:2px
The Three Main Limitations
The Notion API imposes three significant restrictions that directly impacted our implementation:
1. 2000-Character Limit per Text Block
"Error: Content exceeds the maximum limit of 2000 characters per block"
This limit made it impossible to directly create large text blocks, such as articles, extensive documentation, or reports, which are common in productive environments.
2. Special Formatting Required for Markdown
Notion does not accept raw Markdown in its API. Instead, it requires a specific block structure with its own formatting, making the conversion of Markdown content to the API's expected format complex.
3. 100-Block Limit per Request
"Error: Maximum number of blocks per request exceeded (max: 100)"
This limitation meant that even after splitting content into smaller blocks, we still needed to manage multiple requests for very extensive content.
Our Implemented Solution
To work around these limitations, we developed a solution composed of three main components:
1. Smart Content Splitting
We created a "chunking" algorithm that:
- Splits text into blocks smaller than 2000 characters
- Respects content structure (paragraphs, lists, code blocks)
- Preserves Markdown formatting during splitting
- Intelligently handles elements like tables and images
def smart_chunk_content(markdown_text, max_length=1900):
chunks = []
current_chunk = ""
for line in markdown_text.split('\n'):
if len(current_chunk + line + '\n') > max_length:
if current_chunk:
chunks.append(current_chunk)
current_chunk = line + '\n'
else:
current_chunk += line + '\n'
if current_chunk:
chunks.append(current_chunk)
return chunks
2. Markdown to Structured Notion Blocks
We developed a custom Markdown parser that:
- Converts Markdown elements to Notion's block format
- Preserves styles like bold, italic, inline code
- Correctly maps headers, lists, and code blocks
- Maintains links, images, and other complex elements
3. Batch Processing Respecting Block Limits
To handle the 100-block limit per request, we implemented:
- Grouping blocks into batches of up to 100
- A queue system to process requests sequentially
- A retry mechanism with exponential backoff
- Progress monitoring for long operations
Results and Benefits
This solution allowed us to:
- Create Notion pages with virtually unlimited content
- Preserve all original Markdown formatting
- Offer a seamless user experience
- Work around API limitations without compromising functionality
Lessons Learned
Developing this solution taught us:
- The importance of understanding third-party API limitations
- The value of custom algorithms for specific problems
- The need for extensive testing with different content types
- The benefits of a modular approach
"Limitations live only in our minds. But if we use our imagination, our possibilities become limitless." - Jamie Paolinetti