02.06
Build a read-only API or MCP connection (HighLevel and Follow Up Boss)
Create a View-only HighLevel token for Grok through the xAI API, or a GET-only Follow Up Boss export script, with keys stored safely.
Video walkthrough
- Why read-only first: what a write key can do on a bad day
- HighLevel: a Private Integration Token with View scopes only
- Calling HighLevel's MCP server from Grok through the xAI API, with an allow-list
- Follow Up Boss: a GET-only script that writes the CSV for you
- Storing, rotating and revoking keys
What you're building
- HighLevel: a Private Integration Token (PIT) limited to View scopes, used by Grok through the xAI API's Remote MCP tools with an explicit list of read tools.
- Follow Up Boss: a short script that uses GET requests only to pull contacts into the same CSV format as chapter 02.05, so Grok never holds your API key.
Why it matters
A CSV goes stale the moment you export it. A live connection keeps the daily list current, but a key that can write can also tag, enroll or delete. Read-only first means the worst outcome of a mistake is a wrong list, not a changed CRM.
What you need
- Comfort running a command in Terminal, or a developer to do these steps with you
- HighLevel: an agency or sub-account admin who can create Private Integrations
- Follow Up Boss: your API key (each user has one; it carries that user's full access)
- For the HighLevel path: an xAI API account and API key from console.x.ai (billed per token, separate from your Grok app plan)
- A password manager to store keys
Time and cost
- Time
- 60 to 90 minutes
- Cost
- Follow Up Boss path: $0. HighLevel path: xAI API usage billed per token
xAI API prices vary by model and change; check the pricing page in the xAI developer docs before running daily jobs. This setup has not been run end to end by Anu; treat it as a pilot on test data first.
Step by step
Write down the read-only boundary before creating any key
Allowed Not allowed Read contacts, tasks, conversations, pipelines, custom field definitions Create, update or delete contacts Search and list Add or remove tags, enroll in workflows Read message history Send any message, email or call Check: Your boundary table is saved next to your job description from chapter 02.01.
HighLevel: create a View-only Private Integration Token
- Open Settings → Private Integrations. If you do not see it at the agency level, HighLevel says to enable it under Labs. PITs are also available for sub-accounts.
- Click Create new Integration. Name it
Grok CRM Manager (read-only)and add a description with today's date. - Select View scopes only: View Contacts, View Conversations, View Conversation Messages, View Opportunities, View Calendars and View Calendar Events if you want appointments, and View Custom Fields. Leave every Edit scope unchecked.
- Create it and copy the token into your password manager immediately. HighLevel shows it once.
- Copy the sub-account's Location ID into the same password manager entry. You send it as the
locationIdheader.
Check: The integration appears in the Private Integrations list, and its scope list contains no Edit permissions.
HighLevel: call the MCP server from Grok with an allow-list
Use the xAI Responses API with a Remote MCP tool. The
allowed_toolslist is your second lock: even if a token had write scopes, Grok only sees these eight read tools. Replace the placeholders and send the request from a tool like Postman, curl, or a small script. Keep the token out of any file you share.httpxAI Responses request with HighLevel MCP (read tools only) POST https://api.x.ai/v1/responses Authorization: Bearer $XAI_API_KEY Content-Type: application/json { "model": "grok-4.7", "input": [ { "role": "system", "content": "<paste your CRM Manager instructions here>" }, { "role": "user", "content": "Find contacts tagged buyer whose last activity is older than 30 days. Read only. Return Contact ID, name, stage, last activity and why they need attention." } ], "tools": [ { "type": "mcp", "server_url": "https://services.leadconnectorhq.com/mcp/", "server_label": "highlevel", "server_description": "Read-only HighLevel sub-account for Coastal Key Realty", "allowed_tools": [ "contacts_get-contacts", "contacts_get-contact", "contacts_get-all-tasks", "conversations_search-conversation", "conversations_get-messages", "opportunities_search-opportunity", "opportunities_get-pipelines", "locations_get-custom-fields" ], "headers": { "Authorization": "Bearer <PRIVATE_INTEGRATION_TOKEN>", "locationId": "<LOCATION_ID>" } } ] }Check: The response lists real contacts from your sub-account, and the tool calls shown in the response use only tools from your allow-list.
Follow Up Boss: register your system and pull a CSV with GET only
- Get your API key from Admin → API in Follow Up Boss. Store it in your password manager.
- Register your system at Follow Up Boss's system registration page (linked from its Registration and Identification docs) to receive
X-SystemandX-System-Keyvalues. Follow Up Boss asks every API user to register, and requires it if you serve a Follow Up Boss customer. Unregistered requests get lower rate limits. - Save the script below as
fub-export.mjson your computer. It needs Node.js 18 or newer. - Run it with the three values as environment variables, as shown in its first comment. It writes a CSV to the file you name.
- Add the opt-out and consent columns from your account (see the callout), then upload the file to Grok as in chapter 02.05.
javascriptfub-export.mjs (GET-only) // fub-export.mjs: read-only pull of Follow Up Boss people into a CSV. // Run: FUB_API_KEY=... FUB_SYSTEM=... FUB_SYSTEM_KEY=... node fub-export.mjs > crm-export.csv // Uses GET only. Never add POST, PUT or DELETE calls to this file. const key = process.env.FUB_API_KEY; if (!key) throw new Error("Set FUB_API_KEY"); const headers = { Authorization: "Basic " + Buffer.from(key + ":").toString("base64"), "X-System": process.env.FUB_SYSTEM ?? "", "X-System-Key": process.env.FUB_SYSTEM_KEY ?? "", Accept: "application/json", }; const fields = "id,firstName,lastName,emails,phones,source,stage,tags,assignedTo,created,lastActivity"; const q = (v) => '"' + String(v ?? "").replace(/"/g, '""') + '"'; const out = ["Contact ID,First Name,Last Name,Email,Phone,Source,Stage,Tags,Assigned To,Created,Last Activity"]; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); for (let offset = 0; ; offset += 100) { const url = `https://api.followupboss.com/v1/people?limit=100&offset=${offset}&sort=lastActivity&fields=${fields}`; const res = await fetch(url, { method: "GET", headers }); if (res.status === 429) { await sleep(1000 * Number(res.headers.get("Retry-After") ?? 10)); offset -= 100; continue; } if (!res.ok) throw new Error(`HTTP ${res.status}`); const { people = [] } = await res.json(); for (const p of people) { out.push([p.id, p.firstName, p.lastName, p.emails?.[0]?.value, p.phones?.[0]?.value, p.source, p.stage, (p.tags ?? []).join(";"), p.assignedTo, (p.created ?? "").slice(0, 10), (p.lastActivity ?? "").slice(0, 10)].map(q).join(",")); } if (people.length < 100) break; } console.log(out.join("\n"));Check: The CSV opens in a spreadsheet, its row count matches your People count (excluding Trash), and you have added the opt-out columns.
Store, rotate and revoke keys on a schedule
- Keep tokens only in a password manager or environment variables. Never in a Grok chat, a shared document, a Bot you share, or a URL.
- HighLevel recommends rotating PITs every 90 days. Rotate and expire this token later keeps the old and new tokens working for 7 days; Rotate and expire this token now is for a leak.
- Editing a PIT's scopes does not create a new token. Delete the PIT from its three-dot menu when you stop using it.
- For Follow Up Boss, a key leak means the user's full access leaked. Ask the account owner how to reset that user's key, and use the lowest-permission user that can see the contacts you need.
Check: Your password manager entry has a "rotate by" date 90 days from today.
What success looks like
- HighLevel: a View-only PIT and a request whose tool calls stay inside your allow-list
- Follow Up Boss: a GET-only script that produces the chapter 02.05 CSV, with opt-out columns added
- Keys stored in a password manager with a rotation date
Copyable templates
Key name,System,Owner,Scopes or user level,Read-only how,Where stored,Created,Rotate by,Revoked
Grok CRM Manager (read-only),HighLevel PIT,Dana Reyes,View scopes only,Scopes + allowed_tools,Password manager,2026-10-20,2027-01-18,
fub-export,Follow Up Boss API key,Dana Reyes,Agent user,GET-only script,Password manager,2026-10-20,2027-01-18,
xAI API,xAI console,Dana Reyes,Team API key,n/a,Password manager,2026-10-20,2027-01-18,Try it
- Your script→toxAI Responses APIrequest + allowed_tools
- xAI Responses API→toHighLevel MCP8 read tools
- HighLevel MCP→toSub-accountreads
- xAI Responses API→toYour scriptranked answer
How to test it
Prove it cannot write. On a test sub-account or test contact, ask through your HighLevel request: "Add the tag test-write to contact <ID>." The answer should say it has no tool for that, and the contact's tags should be unchanged in HighLevel. For Follow Up Boss, search your script for the words POST, PUT and DELETE: there should be no matches.
Troubleshooting
HighLevel returns 401 Unauthorized.
Check the header is exactly Authorization: Bearer <token> with no extra spaces, the token was not rotated, and the locationId belongs to the sub-account the token was created for.
Grok answers without calling any HighLevel tool.
Make the request specific ("use the highlevel tools to search contacts"), confirm the tool names in allowed_tools match the ones HighLevel lists for your token, and check that the server URL ends with /mcp/.
Follow Up Boss returns 429 Too Many Requests.
The script waits for the Retry-After header and retries. If it happens often, register your system: unregistered requests get 125 requests per 10 seconds globally instead of 250.
Follow Up Boss returns 403 for most requests.
Expired accounts enter a grace period where most endpoints return 403 Forbidden. Check the account's billing status.
Advanced technical details
Optional. You can follow every step above without these.
Technical detailsAuthentication compared
| HighLevel | Follow Up Boss | xAI API | |
|---|---|---|---|
| Credential | Private Integration Token (static OAuth access token) or OAuth app | Per-user API key (Basic auth, key as username, blank password) or OAuth | API key, Bearer auth |
| Least privilege | Choose scopes per token | User role decides access; no read-only key | Team-level; limit tools with allowed_tools |
| Extra headers | Version: 2021-07-28 on API 2.0 calls; locationId for the MCP endpoint | X-System, X-System-Key | None required |
| Rotation | Rotate later (7-day overlap) or now | Ask the account owner | Create a new key, delete the old |
Technical detailsRate limits
- HighLevel API 2.0 (OAuth): 100 requests per 10 seconds burst and 200,000 requests per day, counted per app per sub-account. Read
X-RateLimit-RemainingandX-RateLimit-Daily-Remainingfrom each response. - Follow Up Boss: sliding 10-second window. Registered systems: 250 global, 25 for PUT people, 10 for notes, 20 for GET events. Unregistered: 125 global. A 429 includes
Retry-After; respect it even when remaining looks positive. - xAI API: per-model requests per second and tokens per minute, set by your team's spend tier (Tier 0 starts at $0). Exceeding either returns 429; use exponential backoff.
Technical detailsWebhook basics (for when you want updates pushed, not pulled)
A webhook is the CRM calling your server when something happens, such as a new contact or a stage change, instead of you asking every few minutes. You need a public HTTPS endpoint that answers fast and verifies the sender.
- HighLevel signs webhook bodies. Verify
X-GHL-Signature(Ed25519) with HighLevel's published public key. The legacyX-WH-Signature(RSA) header was scheduled for deprecation on September 1, 2026. Reject requests that fail verification. - Follow Up Boss webhooks can only be created by the account owner and require the
X-Systemheader. Respond with a 2XX within 10 seconds or Follow Up Boss retries. Payloads carry resource IDs and a URI; fetch the record with a GET. Never put an API key in the callback URL.
Technical detailsMCP explained in one paragraph
The Model Context Protocol is an open standard for connecting AI applications to outside systems. An MCP server wraps a system (your CRM) and exposes named tools with defined inputs; an MCP client (Grok, through the xAI API or a custom connector) discovers those tools and calls them during a conversation. The protocol's authorization specification is based on OAuth for HTTP servers. Who controls the server, and which tools it exposes to which token, decides what the AI can do.
Technical detailsData retention on the API path
By default xAI stores API requests and responses, encrypted at rest, for 30 days for abuse auditing, does not train on them, and deletes them after 30 days. Teams with stricter needs can enable Zero Data Retention in the xAI Console (team admins only); it disables stored features such as the stateful Responses API, Files, Collections and the Batch API. A response header x-zero-data-retention reports whether it is on.
Sources
Written from the best available information. One or more steps could not be confirmed; see the notes in the chapter. Last checked 2026-10-20.
- Private Integrations TokenHighLevel Developer Docs · read 2026-10-20
- How to Setup and Use the HighLevel MCP ServerHighLevel Help Center · read 2026-10-20
- ScopesHighLevel Developer Docs · read 2026-10-20
- Rate LimitsHighLevel Developer Docs · read 2026-10-20
- Webhook Integration GuideHighLevel Developer Docs · read 2026-10-20
- Remote MCP ToolsxAI documentation · read 2026-10-20
- Rate LimitsxAI documentation · read 2026-10-20
- Security FAQ (API data retention and ZDR)xAI documentation · read 2026-10-20
- Authentication and AuthorizationFollow Up Boss API Docs · read 2026-10-20
- Registration and IdentificationFollow Up Boss API Docs · read 2026-10-20
- Rate LimitingFollow Up Boss API Docs · read 2026-10-20
- GET /peopleFollow Up Boss API Docs · read 2026-10-20
- WebhooksFollow Up Boss API Docs · read 2026-10-20
- What is the Model Context Protocol (MCP)?Model Context Protocol · read 2026-10-20
- MCP specification: AuthorizationModel Context Protocol · read 2026-10-20