- The sales team curates approved proposals and RFP responses.
- Your application sets up a Sales Hub through the Hubs API to index that content, and embeds the hub portal in the CRM.
- Sales reps query the hub with natural language using Box AI, getting accurate answers grounded in approved, permission-controlled content.
What you are building
By the end of this tutorial, you have a working integration that:- Provisions a Sales Hub programmatically using the Box Hubs API.
- Populates the hub with curated folders containing approved RFP content.
- Embeds the hub’s AI chat interface in your CRM.
- Queries the hub using Box AI to answer sales questions grounded in approved content.
Prerequisites
Before you start, make sure you have the following:- A with Box Hubs enabled. See .
- A Box application configured with Client Credentials Grant authentication and Generate User Access Tokens enabled.
- Python 3.11 or higher.
- The following scopes enabled on your app:
- Read and write all files and folders stored in Box
- Manage AI
- Your Box user ID (found in the Admin Console under Users).
Step-by-step process
This solution combines three Box Platform capabilities:| Component | Purpose | API |
|---|---|---|
| Hubs | Index curated content into a searchable, permission-inheriting portal | POST /2.0/hubs |
| Hub items | Add folders and files to the hub | POST /2.0/hubs/:id/manage_items |
| Box AI | Answer natural language questions grounded in hub content | POST /2.0/ai/ask |
Organize your RFP content in Box
Sales Content folder and each subfolder. You use these when adding items to the hub.Set up the development environment
- Open your terminal and create a new project directory:
- Create and activate a Python virtual environment:
(.venv) at the beginning. This confirms you are working inside the virtual environment.source .venv/bin/activate from the project directory. If you see ModuleNotFoundError when running commands, it usually means the venv is not activated.- Install the required packages:
- Create a
.envfile to store your credentials then add the following content. Replace the placeholder values with your actual credentials from the Box Developer Console:
.env file stores sensitive values (your actual credentials). Your Python code reads these values by referencing their names using os.getenv("VARIABLE_NAME"). For example, os.getenv("BOX_CLIENT_ID") looks up the value stored next to BOX_CLIENT_ID= in your .env file. When you copy the code in the following steps, keep the quoted variable names exactly as shown. Do not replace them with your actual credentials.Authenticate the Box client
box_client.py in your project directory. Open the file and paste the following code:user_id (not enterprise_id) to authenticate as a specific Box user. This means the client acts with that user’s permissions and can access content the user has been invited to. Find your user ID in the Admin Console under Users, or by clicking your avatar in the Box web app and checking the URL.Provision the Sales Hub
create_hub.py. This script creates a new hub and populates it with your sales content folders:Manage hub access
manage_access.py:Query the hub with Box AI
query_hub.py:Test the integration
sales-rfp-hub directory and the virtual environment is activated before running any commands:invalid_client, check your .env credentials.2. Create the hub and add content:query_hub.py and manage_access.py and replace YOUR_HUB_ID with this value.3. Query the hub:- The hub ID is correct.
- The content folder contains documents (not just subfolders).
- Enough time has passed for indexing to complete.
Keep the hub current
Troubleshooting
ModuleNotFoundError: No module named '...'
ModuleNotFoundError: No module named '...'
source .venv/bin/activate from the project directory before running any python commands. Each new terminal tab needs its own activation.invalid_client: The client credentials are invalid
invalid_client: The client credentials are invalid
.env file:- Verify
BOX_CLIENT_IDandBOX_CLIENT_SECRETmatch the values in Developer Console > Platform Apps > App > Configuration. - Confirm
BOX_USER_IDis a valid Box user ID (numeric, found in Admin Console > Users). - Ensure your app is authorized in the Developer Console.
- Confirm the app type is Client Credentials Grant with Generate User Access Tokens enabled.
403 Forbidden or 'access_denied_insufficient_permissions'
403 Forbidden or 'access_denied_insufficient_permissions'
- Verify that Read all files and folders and Write all files and folders scopes are enabled on your app.
- Confirm the Manage AI scope is enabled (required for Box AI queries).
- If using a service account, ensure it has been invited as a collaborator on the content folders.
404 Not Found when creating the hub or adding items
404 Not Found when creating the hub or adding items
- The folder ID in your
.envfile matches the URL in Box (https://app.box.com/folder/123456789means the folder ID is123456789). - The user specified in
BOX_USER_IDhas at least Viewer access to the folder.
Box AI returns empty or irrelevant answers
Box AI returns empty or irrelevant answers
- Wait a few minutes after adding content before querying. Indexing is not instantaneous.
- Verify the hub contains files (not just empty folders) by checking in the Box web app under Hubs.
- Ensure your documents contain text content (scanned image PDFs without OCR are not searchable).
- Try asking a question that directly relates to content you know exists in the hub.
Hub not visible in Box web app
Hub not visible in Box web app
manage_access.py to add yourself or check the hub owner. Alternatively, verify Box Hubs is enabled for your enterprise by checking with your Box administrator.Embed the hub in your CRM
You can embed the hub’s AI chat interface directly into your CRM (such as Salesforce, HubSpot, or a custom internal tool), giving reps a focused chatbot experience powered by the hub’s content. Box supports two embed modes for hub AI chat: a chat button and a chat widget. For the full list of embed parameters and options, see .Scaling to production
Automate hub provisioning for multiple teams
Automate hub provisioning for multiple teams
create_sales_hub in create_hub.py to accept an optional title parameter instead of the hardcoded value. Then loop over your teams:Build a conversational RFP assistant
Build a conversational RFP assistant
POST /2.0/ai/ask endpoint accepts a dialogue_history parameter that carries previous Q&A pairs. Maintain a list of exchanges and pass it with each request so reps can ask follow-ups like “Can you elaborate on the data residency point?” without losing context.Add the following to query_hub.py, or create a new script with the same imports and client setup:Track usage and measure impact
Track usage and measure impact
Enforce content governance
Enforce content governance
