Make.com Integration¶
Make.com (formerly Integromat) is a visual automation platform that connects apps and services through scenarios. By integrating Make.com with Beyond Retrieval v2, you can build automated pipelines for document ingestion, RAG-powered chatbots, scheduled health monitoring, and instant Q&A from form submissions.
Prerequisites¶
| Requirement | Details |
|---|---|
| Make.com account | Free or paid plan |
| Beyond Retrieval API | Running and reachable from Make.com (public URL or tunnel) |
| Bearer token | A valid JWT token (or any string when BYPASS_AUTH=true in dev mode) |
| Notebook ID | At least one notebook created in Beyond Retrieval |
Local Development with Make.com
Make.com runs in the cloud and cannot reach localhost. Use a tunneling service (e.g., ngrok, Cloudflare Tunnel) to expose your local Beyond Retrieval instance, or deploy to a server with a public IP.
Authentication Setup¶
Make.com does not have a built-in Beyond Retrieval connector, so you will use the HTTP module with manual header configuration.
Option A: Header in Each Module¶
Add the Authorization header directly to every HTTP module:
| Header Name | Header Value |
|---|---|
Authorization | Bearer <your_token> |
Option B: Reusable Connection (Recommended)¶
Create a custom connection for reuse across modules:
- In your scenario, add an HTTP > Make a request module.
- Click Add next to the connection dropdown.
- Select API Key as the type.
- Configure:
| Field | Value |
|---|---|
| Connection name | Beyond Retrieval API |
| Key | Authorization |
| Value | Bearer <your_token> |
| Placement | Header |
- Save the connection. It can be reused in all HTTP modules within your scenarios.
Token Security
Store tokens in Make.com's connection system rather than hardcoding them in module fields. This centralizes token rotation and prevents accidental exposure in scenario exports.
HTTP Module — Base Configuration¶
Every API call uses the HTTP > Make a request module with these defaults:
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/... (or tunneled localhost) |
| Method | Varies per endpoint |
| Headers | Authorization: Bearer <token>, Content-Type: application/json |
| Body type | Raw > JSON |
| Parse response | Yes |
| Timeout | 300 seconds (for RAG calls) |
Parsing the Response Envelope¶
Beyond Retrieval wraps every response in a standard envelope:
In Make.com, after the HTTP module executes with Parse response: Yes, access fields with dot notation:
{{data.assistant_message.content}}— AI response text{{data.health_score}}— health check score{{success}}— boolean success flag{{error}}— error message (null on success)
JSON Parsing
When Parse response is set to Yes, Make.com automatically parses the JSON body. You can then map any field using the module's output mapping panel.
Example Scenarios¶
1. Google Drive to Beyond Retrieval Ingestion¶
Watch a Google Drive folder for new files, download them, upload to Beyond Retrieval, and trigger ingestion.
graph LR
A[Google Drive: Watch Files] --> B[Google Drive: Download File]
B --> C[HTTP: Upload to BR]
C --> D[Router]
D -->|Success| E[HTTP: Start Ingestion]
D -->|Failure| F[Slack: Notify Error]
E --> G[Sleep 15s]
G --> H[HTTP: Check Stage]
H --> I[Router]
I -->|Processing| G
I -->|Done| J[Slack: Notify Complete] Module 1 — Google Drive: Watch Files
| Setting | Value |
|---|---|
| Folder | Select your target folder |
| Watch | New files only |
| Limit | 10 |
Module 2 — Google Drive: Download a File
| Setting | Value |
|---|---|
| File ID | {{1.id}} (mapped from Watch module) |
Module 3 — HTTP: Upload to Beyond Retrieval
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/<NOTEBOOK_ID>/documents/upload |
| Method | POST |
| Body type | Multipart/form-data |
Add a field:
| Field name | File name | Data |
|---|---|---|
files | {{2.fileName}} | Map from the Google Drive Download module's binary data |
Module 4 — Router
Add a router with two routes:
- Route 1 (Success): Filter condition
{{3.data.success}}equalstrue - Route 2 (Failure): Fallback route
Module 5 — HTTP: Start Ingestion
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/<NOTEBOOK_ID>/documents/ingest |
| Method | POST |
| Body type | Raw > JSON |
{
"files": [
{
"file_id": "{{3.data[1].file_id}}",
"file_name": "{{3.data[1].file_name}}",
"file_path": "{{3.data[1].storage_path}}"
}
],
"settings": {
"parser": "Docling Parser",
"chunking_strategy": "Recursive Chunking",
"chunk_size": 1000,
"chunk_overlap": 200
}
}
Module 6 — Sleep
| Setting | Value |
|---|---|
| Delay | 15 seconds |
Module 7 — HTTP: Check Stage
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/<NOTEBOOK_ID>/documents/{{3.data[1].file_id}}/stage |
| Method | GET |
Module 8 — Router (Poll Loop)
- Route 1 (Still Processing): Filter
{{7.data.status}}equalsProcessing— loop back to Sleep module using a Repeater with max iterations set to 20 - Route 2 (Done): Filter
{{7.data.status}}does not equalProcessing— proceed to notification
Repeater Pattern
Make.com does not have native loops. Use a Repeater module or create a separate scenario triggered by webhook to implement polling. Alternatively, set up a second scenario on a 30-second schedule that checks the stage and stops when processing completes.
2. Slack Bot with RAG Chat¶
Build a Slack bot that answers questions using your Beyond Retrieval knowledge base.
graph LR
A[Slack: Watch Messages] --> B[Filter: Is Question?]
B --> C[HTTP: Create Conversation]
C --> D[HTTP: Send RAG Message]
D --> E[Router]
E -->|Success| F[Slack: Reply in Thread]
E -->|Failure| G[Slack: Reply with Error] Module 1 — Slack: Watch New Messages
| Setting | Value |
|---|---|
| Channel | Select the channel to monitor |
| Filter | Messages only (no bot messages) |
Module 2 — Filter
Filter out messages that should not trigger a RAG query:
| Condition | Value |
|---|---|
| Text | Does not start with / (ignore slash commands) |
| User | Is not a bot |
Module 3 — HTTP: Create Conversation
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/<NOTEBOOK_ID>/conversations |
| Method | POST |
| Body | {"title": "Slack - {{1.user}}", "chat_mode": "rag"} |
Conversation Persistence
For multi-turn conversations, use Make.com's Data Store module to save and look up conversation IDs per Slack user or thread. Create a conversation only when no existing one is found.
Module 4 — HTTP: Send RAG Message
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/<NOTEBOOK_ID>/conversations/{{3.data.conversation_id}}/messages |
| Method | POST |
| Body type | Raw > JSON |
| Timeout | 300 seconds |
{
"content": "{{1.text}}",
"chat_mode": "rag",
"strategy_id": "fusion",
"persona": "professional",
"language": "en"
}
Module 5 — Router
- Success route:
{{4.success}}equalstrue - Error route: fallback
Module 6 — Slack: Post Reply
| Setting | Value |
|---|---|
| Channel | {{1.channel}} |
| Text | {{4.data.assistant_message.content}} |
| Thread Timestamp | {{1.ts}} (reply in thread) |
Timeout Considerations
RAG pipeline calls can take 5-30 seconds. Make.com's default timeout is 40 seconds. Increase the HTTP module timeout to 300 seconds to avoid premature failures. Slack expects a response within 3 seconds for interactive messages, but Watch-based triggers do not have this constraint.
3. Scheduled Health Monitoring with Email¶
Check all notebook health scores daily and send a summary email.
graph LR
A[Schedule: Daily 8am] --> B[HTTP: List Notebooks]
B --> C[Iterator]
C --> D[HTTP: Health Check]
D --> E[Array Aggregator]
E --> F[Filter: Any Unhealthy?]
F --> G[Email: Send Report] Module 1 — Schedule
| Setting | Value |
|---|---|
| Run scenario | Every day at 08:00 |
Module 2 — HTTP: List Notebooks
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/ |
| Method | GET |
Module 3 — Iterator
| Setting | Value |
|---|---|
| Array | {{2.data}} |
This iterates over each notebook in the list.
Module 4 — HTTP: Health Check
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/{{3.notebook_id}}/health |
| Method | GET |
Module 5 — Array Aggregator
Collect all health check results into a single array for processing.
| Setting | Value |
|---|---|
| Source Module | HTTP: Health Check |
Module 6 — Filter: Any Unhealthy?
Check if any notebook has a health score below 70:
| Condition | Value |
|---|---|
| Expression | Array contains item where health_score < 70 |
Module 7 — Email: Send Report
Compose an HTML email with the health summary. Use Make.com's text aggregator or a template to format the results:
Subject: Beyond Retrieval Health Report — {{formatDate(now; "YYYY-MM-DD")}}
Notebooks with health score below 70:
{{#each 5.array}}
- {{this.notebook_id}}: Score {{this.data.health_score}}/100
Duplicates: {{this.data.duplicate_count}} | Orphans: {{this.data.orphaned_count}}
{{/each}}
Automatic Cleanup
Add a branch after the health check: if duplicate_count > 0, call POST /api/notebooks/{id}/health/cleanup to remove duplicates before sending the report.
4. Form Submission to Auto-Answer¶
Accept a question via a webhook form, query the RAG pipeline, and return the answer.
graph LR
A[Webhooks: Custom Webhook] --> B[HTTP: Create Conversation]
B --> C[HTTP: Send RAG Message]
C --> D[Router]
D -->|Success| E[Webhook Response: Answer]
D -->|Failure| F[Webhook Response: Error] Module 1 — Webhooks: Custom Webhook
| Setting | Value |
|---|---|
| Webhook name | Beyond Retrieval Q&A |
| Data structure | Add: question (text), notebook_id (text), language (text, optional) |
Expected request body:
Module 2 — HTTP: Create Conversation
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/{{1.notebook_id}}/conversations |
| Method | POST |
| Body | {"title": "Form Q&A", "chat_mode": "rag"} |
Module 3 — HTTP: Send RAG Message
| Setting | Value |
|---|---|
| URL | https://your-domain.com/api/notebooks/{{1.notebook_id}}/conversations/{{2.data.conversation_id}}/messages |
| Method | POST |
| Timeout | 300 seconds |
{
"content": "{{1.question}}",
"chat_mode": "rag",
"strategy_id": "fusion",
"persona": "professional",
"language": "{{ifempty(1.language; \"en\")}}"
}
Module 4 — Router
- Success:
{{3.success}}equalstrue - Failure: fallback
Module 5 — Webhook Response (Success)
| Setting | Value |
|---|---|
| Status | 200 |
| Body | JSON with answer |
{
"answer": "{{3.data.assistant_message.content}}",
"citations": {{3.data.assistant_message.citations}},
"is_cached": {{3.data.assistant_message.run_metadata.is_cached}},
"suggested_questions": {{3.data.assistant_message.run_metadata.suggested_questions}}
}
Module 6 — Webhook Response (Error)
| Setting | Value |
|---|---|
| Status | 500 |
| Body | {"error": "{{3.error}}"} |
Error Handling¶
Error Routes¶
Make.com supports error handler routes on every module. Right-click any module and select Add error handler to create a fallback path.
Common error handler modules:
| Module | Use Case |
|---|---|
| Resume | Continue execution with a default value |
| Commit | Save partial results and stop |
| Rollback | Discard partial results and retry |
| Break | Stop execution and move item to incomplete queue |
| Ignore | Suppress the error and continue |
Retry Logic¶
Configure automatic retries in scenario settings:
| Setting | Value |
|---|---|
| Number of consecutive errors | 3 |
| Interval between errors | 60 seconds |
For individual HTTP modules, use a Break error handler with the Automatically complete execution option to retry failed operations:
- Add a Break module as an error handler on the HTTP module.
- Enable Automatically complete execution.
- Set Number of attempts to
3. - Set Interval to
30seconds.
429 Rate Limits
When Beyond Retrieval returns HTTP 429 (LLM provider rate limit), the response includes a Retry-After header. Use a Break error handler with an interval matching the retry-after value (typically 10-60 seconds).
Variable Mapping Patterns¶
Accessing Nested Response Data¶
Beyond Retrieval responses use a nested structure. Here are common mapping patterns:
| What you need | Make.com expression |
|---|---|
| AI answer text | {{X.data.assistant_message.content}} |
| First citation source | {{X.data.assistant_message.citations[1].metadata.file_name}} |
| Health score | {{X.data.health_score}} |
| Upload file ID | {{X.data[1].file_id}} |
| Job status | {{X.data.status}} |
| Conversation ID | {{X.data.conversation_id}} |
| Is cached response | {{X.data.assistant_message.run_metadata.is_cached}} |
| Suggested questions | {{X.data.assistant_message.run_metadata.suggested_questions}} |
Replace X with the module number in your scenario.
Conditional Values¶
Use Make.com's ifempty and if functions:
// Default language to English
{{ifempty(1.language; "en")}}
// Choose persona based on channel
{{if(1.channel = "C123SUPPORT"; "professional"; "funny")}}
Array Iteration¶
When processing multiple items (e.g., notebook list, document list), use the Iterator module to split arrays and the Array Aggregator to recombine results.
Tips and Best Practices¶
| Topic | Recommendation |
|---|---|
| Timeouts | Set HTTP module timeout to 300 seconds for RAG and ingestion calls |
| File uploads | Use Multipart/form-data body type with field name files |
| Polling | Use Repeater or separate scheduled scenarios for ingestion status checks |
| Data stores | Use Make.com Data Stores to persist conversation IDs across scenario runs |
| Scheduling | Health checks: daily. Ingestion watches: every 15 minutes. Chat: instant (webhook-based) |
| Error handling | Add Break error handlers on all HTTP modules for automatic retry |
| Testing | Use Run once mode to test individual modules before activating the scenario |
| Operations budget | Each HTTP call = 1 operation. A RAG chat scenario uses minimum 3 operations (create conv + send msg + reply) |
| Webhooks | Make.com webhook URLs are permanent — save them securely and do not regenerate unnecessarily |
| Scenario organization | Use folders and naming conventions: [BR] Health Monitor, [BR] Slack Bot, etc. |
Quick Reference — Common API Calls¶
| Action | Method | URL Path | Body |
|---|---|---|---|
| List notebooks | GET | /api/notebooks/ | -- |
| Create notebook | POST | /api/notebooks/ | {notebook_id, notebook_title, user_id} |
| Upload file | POST | /api/notebooks/{id}/documents/upload | multipart files |
| Start ingestion | POST | /api/notebooks/{id}/documents/ingest | {files, settings} |
| Check stage | GET | /api/notebooks/{id}/documents/{fid}/stage | -- |
| List documents | GET | /api/notebooks/{id}/documents/ | -- |
| Health check | GET | /api/notebooks/{id}/health | -- |
| Cleanup duplicates | POST | /api/notebooks/{id}/health/cleanup | -- |
| Create conversation | POST | /api/notebooks/{id}/conversations | {title, chat_mode} |
| Send RAG message | POST | /api/notebooks/{id}/conversations/{cid}/messages | {content, strategy_id} |
| Submit feedback | POST | /api/notebooks/{id}/messages/{mid}/feedback | {is_positive} |
| Get settings | GET | /api/notebooks/{id}/settings | -- |