Most chatbot integrations start with a widget snippet and stall at the security review. The reviewer asks how credentials are scoped, where events go, and how changes get deployed. The snippet answers none of that.
SiteGPT exposes the same account through a REST API, three SDKs, a CLI, and an MCP server. This guide covers how to secure each one, connect it to your systems, and automate it.
iShort answer
SiteGPT API v2 lives at https://sitegpt.ai/api/v2 and takes a bearer token that starts with sgpt_. Tokens are scoped per area (for example knowledge:write), can be limited to specific chatbots, and expire after 90 days by default. Conversation context is held server-side under a threadId, so follow-up calls send only the new message. Webhooks push messages, escalations, and leads to your URL, authenticated by a shared token header. The CLI wraps the same API with --json and --wait for CI/CD. API access needs the Growth plan or above, and webhooks need Scale or the webhook add-on.
Every surface acts on the same account data through API v2, and none can do more than the dashboard role behind its credential.
REST API v2 and SDKs
Backend and product integrations. Requests use a bearer token and return one JSON envelope. Clients exist for TypeScript, Python, and Go.
CLI
Scripts and CI/CD. The same operations as shell commands, with --json output, non-zero exits on failure, and --wait for training.
MCP server
AI assistants. A hosted server with browser OAuth, or a local stdio server that uses an API token.
Webhooks
Events out to your systems. Messages, escalations, and new leads are sent as POST requests to a URL you own.
Which SiteGPT integration surface should you use?
Use API v2 or an SDK when code in your own product talks to SiteGPT. Use the CLI when a script or pipeline does. Use MCP when an AI assistant does. Use webhooks when your systems need to react to something that happened in a chat.
| Job | Surface | Credential |
|---|---|---|
| Call SiteGPT from a backend service | API v2 or an SDK | API token (sgpt_...) |
| Deploy content and settings from a pipeline | CLI | API token in SITEGPT_API_TOKEN |
| Let an AI assistant operate the account | MCP server | OAuth approval (remote) or API token (local) |
| Create a ticket or CRM record from a chat event | Webhooks | Shared token in X-WEBHOOK-TOKEN |
| Sign in a known visitor inside the widget | Widget SDK | HMAC signature made on your server |
The SDKs are thin clients over the same API. @sitegpt/sdk on npm is typed from the OpenAPI document. sitegpt on PyPI uses only the Python standard library. A Go client is also published.
How do you plan a secure API integration?
Decide what each integration is allowed to do before writing any code. Then issue a token that can do only that, and give it an expiry date. The API enforces the rest.
How does authentication work?
API v2 accepts one credential type: an API token sent as a bearer header.
curl https://sitegpt.ai/api/v2/me \
-H "Authorization: Bearer $SITEGPT_API_TOKEN"
A token can come from three places:
- The Agents page in the dashboard. SiteGPT shows the token value once.
- OAuth device login.
sitegpt loginuses it, so nobody pastes a token into a tool. A person approves the request in the browser and can narrow the access there. - The tokens endpoint,
POST /api/v2/tokens, for teams that issue credentials from code. It needs thetokens:writescope.
The health endpoint needs no token, so it is a safe first call from a new network segment:
curl https://sitegpt.ai/api/v2/health
{"ok":true,"data":{"status":"ok","service":"sitegpt","time":"2026-10-13T06:20:49.262Z"},"meta":{"requestId":"a49c3d96d94649d6"}}
How do you scope a token to least privilege?
Three controls narrow a token: scopes, chatbot access, and expiry. Set all three for every integration.
Scopes. Each scope allows one kind of action on one area, in the form area:read, area:write, or area:delete. The areas are account, billing, tokens, chatbots, knowledge, personas, instructions, settings, starters, followups, conversations, leads, members, and integrations.
Chatbot access. A token can follow every chatbot the creator can reach, or only the chatbots you list. Pick specific chatbots for any tool that works on one bot.
Expiry. The dashboard offers 30, 90, 180, or 365 days, and 90 is the default. The API accepts any value from 1 to 365 days, or an absolute expiresAt timestamp.
This request creates a token that can update content on one chatbot and nothing else:
curl -X POST https://sitegpt.ai/api/v2/tokens \
-H "Authorization: Bearer $SITEGPT_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "docs-sync-pipeline",
"scopes": ["chatbots:read", "knowledge:read", "knowledge:write"],
"chatbotIds": ["YOUR_CHATBOT_ID"],
"expiresInDays": 30
}'
The dashboard also offers four preset access levels:
| Access level | What the token can do |
|---|---|
| Standard (default) | Everything except creating or changing tokens, changing billing, and reading or changing integrations |
| Read only | Every read permission, with no writes and no deletes |
| Full | Every permission the creator's dashboard role can give |
| Custom | Only the permissions selected in a Read, Write, and Delete table |
Two rules apply to every token. A token never gets more access than the person who created it. Billing scopes, and chatbots:write across all chatbots, need an account owner.
How do you store, rotate, and revoke tokens?
Keep the token in a secret manager or the CI secret store, and read it from SITEGPT_API_TOKEN. Do not pass it as a command-line argument, because arguments land in shell history and build logs.
- Rotate with
POST /api/v2/tokens/{tokenId}/rotateorsitegpt tokens rotate. The new value keeps the same settings and the old value stops working. - Revoke with
DELETE /api/v2/tokens/{tokenId}orsitegpt tokens revoke. The token stops at once. - Audit on the Agents page. The token list shows the scopes, status, and source of every token. The source is manual token, device login, or onboarding token.
What does the API return when a request is refused?
Every response uses one envelope: ok, then data or error, then meta.requestId. Branch on error.code. The docs state that error.message can change.
A request with no credential, captured on 2026-10-13:
curl -i https://sitegpt.ai/api/v2/me
HTTP/2 401
www-authenticate: Bearer realm="SiteGPT", resource_metadata="https://sitegpt.ai/.well-known/oauth-protected-resource/api/v2"
{"ok":false,"error":{"code":"AUTHORIZATION_HEADER_REQUIRED","message":"Authorization header is required"},"meta":{"requestId":"a49c3d9938228adc"}}
| Status | Code | What to do |
|---|---|---|
| 401 | TOKEN_NOT_VALID | The token is wrong, expired, or revoked. Issue a new one. |
| 403 | TOKEN_SCOPE_NOT_ALLOWED | Read error.details.requiredScopes and add the missing scope. |
| 403 | PLAN_UPGRADE_REQUIRED | The plan does not include API access. |
| 400 | CONFIRMATION_REQUIRED | A delete was sent without confirm=true. Nothing was deleted. |
| 429 | CHATBOT_PAGES_LIMIT_REACHED | A plan quota is used up. Do not retry in a loop. |
Deletes need an explicit confirm=true, so a script with a wrong variable does not remove data by accident. Send your own x-request-id header and SiteGPT echoes it in meta.requestId, which lets you trace one call across both sets of logs.
What should a security review know?
SiteGPT's security documentation states these points:
- All data is encrypted in transit with TLS 1.2 or higher, and at rest.
- SiteGPT completed a SOC 2 Type II examination covering security, availability, and confidentiality.
- Content and conversations are not used to train AI models.
- Each chatbot searches only its own content. Content is not shared between chatbots or customers.
- Data is stored mostly in the United States. SiteGPT does not offer EU-only hosting, and the data residency guide covers what that means for a transfer assessment.
Raise three limits in the review:
- The API publishes no per-request rate limit and sends no rate-limit headers. Add your own client-side throttle.
- Webhook requests are not signed.
- Webhook deliveries are not retried.
The webhook section below shows how to design around the last two.
How do you build custom workflows and data connections?
A typical integration has two directions. Content flows in from your systems so the chatbot can answer from it. Events flow out so your helpdesk and CRM can act on them.
Pull-based calls use an API token. Push-based events use a webhook token.
Into SiteGPT (API v2)
- Add pages, sitemaps, files, and text as knowledge
- Set a sync frequency so content refreshes on a schedule
- Send a visitor message and read the answer
- Escalate a conversation or reply as your team
- Update settings, personas, and instructions
Out of SiteGPT (webhooks)
- ADD_MESSAGE for every saved message
- CONVERSATION_ESCALATED when a chat needs a person
- CONVERSATION_ESCALATED_UPDATED when contact details arrive
- NEW_LEAD_CAPTURE when the bot collects a lead
- One POST per event, with no retry
How do you connect your own content?
Use the knowledge endpoints. Each one takes a different source type under /api/v2/chatbots/{chatbotId}/knowledge/:
| Endpoint | Adds |
|---|---|
POST .../knowledge/links | Up to 1,000 individual URLs per call |
POST .../knowledge/website | A crawl from a starting URL |
POST .../knowledge/sitemap | Every page in a sitemap |
POST .../knowledge/files | Uploaded files |
POST .../knowledge/text | A freeform text document |
POST .../knowledge/youtube | YouTube videos |
POST .../knowledge/sources | A connected source such as GitHub or Confluence |
Adding one docs page looks like this:
curl -X POST "https://sitegpt.ai/api/v2/chatbots/$SITEGPT_CHATBOT_ID/knowledge/links" \
-H "Authorization: Bearer $SITEGPT_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "urls": ["https://example.com/docs/getting-started"] }'
Ingestion is asynchronous. GET .../documents/stats reports how many documents are trained, pending, or failed, and GET .../ingest-jobs lists scheduled sync jobs. The CLI wraps the polling in one flag, covered in the deployment section below.
Internal systems with no public URL fit the text and files endpoints. A nightly job can export approved help articles from your knowledge base and post them as text documents. The content ingestion guide explains what happens to a document after it arrives.
How do you send conversation events to your systems?
Set up to three webhook URLs per chatbot in Settings > Webhooks: one for messages, one for escalations, and one for leads. Each URL has its own token, and SiteGPT sends that token in the X-WEBHOOK-TOKEN header.
Two delivery facts shape the handler design:
- Requests are not signed. The token header is the only proof of origin. Use a long random value per URL and reject any request where it does not match.
- Each event is sent once. SiteGPT does not retry a failed delivery and does not read your response status.
A handler that follows both rules:
// Node.js with Express
const crypto = require('crypto');
function tokenMatches(received) {
const expected = Buffer.from(process.env.SITEGPT_WEBHOOK_TOKEN);
const actual = Buffer.from(received || '');
return actual.length === expected.length && crypto.timingSafeEqual(actual, expected);
}
app.post('/sitegpt-webhook', express.json(), (req, res) => {
if (!tokenMatches(req.get('X-WEBHOOK-TOKEN'))) {
return res.status(401).end();
}
// Answer first, then do the work
res.status(200).end();
const { event, data } = req.body;
if (event === 'CONVERSATION_ESCALATED') {
queue.add('create-ticket', { threadId: data.threadId, url: data.dashboardUrl });
}
if (event === 'CONVERSATION_ESCALATED_UPDATED') {
queue.add('update-ticket', { threadId: data.threadId, user: data.user });
}
if (event === 'NEW_LEAD_CAPTURE') {
queue.add('upsert-crm-contact', data.leadDetails);
}
});
Because nothing is retried, pair the webhook with a reconciliation job. Once an hour, list escalated conversations and recent leads through API v2 and create anything your system is missing. Use threadId and the lead id as idempotency keys. The docs note that an escalation event can arrive twice after an internal error.
How do you build an escalation workflow?
Create the ticket on CONVERSATION_ESCALATED and update it on CONVERSATION_ESCALATED_UPDATED, matched by threadId. The second event carries the visitor's contact details once they provide them.
Your own code can also drive the handoff through the API:
POST .../conversations/{threadId}/escalateflags a conversation for your team.POST .../conversations/{threadId}/take-overstops the AI from answering.POST .../conversations/{threadId}/repliessends a reply as a team member.POST .../conversations/{threadId}/switch-to-aihands the conversation back.
SiteGPT also has native integrations with Slack, Crisp, and Zendesk for teams that do not want to write this glue. A conversation that lives in one of those channels must be answered there. A team reply sent through the API returns 409 REPLY_IN_CHANNEL.
How do you identify signed-in users in the widget?
Sign the user's email on your server and pass the signature to the widget. The signature is the HMAC-SHA256 of the email address, keyed with the legacy API key from the Billing page, as a lowercase hex string.
// Server: never send the key to the browser
const signature = crypto
.createHmac('sha256', process.env.SITEGPT_API_KEY)
.update(user.email)
.digest('hex');
// Browser
window.$sitegpt.push(['set', 'user:email', [user.email, signature]]);
If the signature does not match, the visitor stays anonymous and the widget shows no error. Treat the key like a password. Anyone who holds it can sign in as any email address on your chatbots.
How do SiteGPT chatbots keep context across API calls?
SiteGPT stores the conversation and identifies it with a threadId. Your code keeps one string per conversation and sends only the new message each time.
This differs from calling a language model API directly. There, the client usually resends earlier messages on every call and has to trim or summarize them as the history grows. With SiteGPT, the history stays on the server.
Start a conversation. The first message goes to the chatbot:
curl -X POST "https://sitegpt.ai/api/v2/chatbots/$SITEGPT_CHATBOT_ID/messages" \
-H "Authorization: Bearer $SITEGPT_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "message": "What are your opening hours?" }'
The call waits for the answer. The response carries data.conversation.threadId, the answer text in data.message.answer.text, and the source URLs in data.message.sources.
Continue it. Follow-ups go to the conversation:
curl -X POST "https://sitegpt.ai/api/v2/chatbots/$SITEGPT_CHATBOT_ID/conversations/$SITEGPT_THREAD_ID/messages" \
-H "Authorization: Bearer $SITEGPT_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "message": "And on public holidays?" }'
Three details matter when you build on this:
- Page context. Both message endpoints accept an optional
pageUrl. In the widget,['set', 'context', ...]adds page or visitor context to the chatbot's answers. - Conversation state. A resolved conversation rejects new messages with
409 CONVERSATION_CLOSED. When a team member has taken over, the API saves the visitor's message and the AI does not answer. - Away messages. When the team holds a conversation outside working hours, the response includes an
awayMessageonce. Show its text to the visitor.
Map your own session id to the threadId in your database. When a 409 CONVERSATION_CLOSED comes back, start a new conversation and store the new id.
How do you automate SiteGPT deployment in a CI/CD pipeline?
Run the SiteGPT CLI in the pipeline with a scoped token. It gives a pipeline four properties that raw API calls would need extra code for:
| CLI feature | Why a pipeline needs it |
|---|---|
SITEGPT_API_TOKEN from the environment | No interactive login, and the secret never appears in a command |
--json on every command | A stable envelope with an ok field and an error.code to branch on |
| Non-zero exit on failure | A failed step stops the job |
--wait on knowledge commands | The command blocks until training settles, so the next step never reads a half-trained bot |
A GitHub Actions job that re-syncs the docs after a merge and then tests the bot:
name: Sync chatbot knowledge
on:
push:
branches: [main]
paths: ["docs/**"]
jobs:
sync:
runs-on: ubuntu-latest
env:
SITEGPT_API_TOKEN: ${{ secrets.SITEGPT_API_TOKEN }}
CHATBOT_ID: ${{ vars.SITEGPT_CHATBOT_ID }}
steps:
- run: npm install -g @sitegpt/cli
- name: Re-ingest the docs sitemap and wait for training
run: |
sitegpt knowledge sitemap add https://example.com/docs/sitemap.xml \
--chatbot "$CHATBOT_ID" --wait --timeout 600 --json
- name: Smoke test
run: |
sitegpt messages send "What is the refund window?" \
--chatbot "$CHATBOT_ID" | grep -q "30 days"
The smoke test turns answer quality into a build gate. Pick three to five questions whose answers contain a fixed fact, and fail the job when the fact is missing. A wrong answer then blocks the deploy the same way a failing unit test does.
Three practices keep the pipeline safe:
- One token per pipeline. Scope it to
chatbots:read,knowledge:read,knowledge:write, andconversations:writeon one chatbot. Give it a 90-day expiry and rotate it on a schedule. - A staging chatbot. Run changes against a second chatbot first, test, then apply the same commands to production. Named profiles (
sitegpt -p staging ...) keep the two apart. - Settings in git.
sitegpt settings get --jsonexports the current settings, andsitegpt settings updateapplies them from a JSON file. Reviewing that file in a pull request gives a change history the dashboard alone does not.
The full command walkthrough, including the public onboarding flow that needs no account, is in the chatbot CLI guide. SiteGPT also publishes a setup guide for running the CLI from Codex in CI pipelines.
Where does MCP fit in an enterprise setup?
MCP is the surface for AI assistants. Scheduled jobs belong on the API or the CLI. Use MCP when a person wants an assistant to read conversations, add content, or change settings by asking.
The remote server at https://sitegpt.ai/mcp authenticates with OAuth in the browser, so no token is pasted into a chat. Its approval page has a Read only option. That option fits analysts who should see conversations and leads and change nothing. The MCP server page covers the connection steps and the three tools that reach all of API v2: search, execute_read, and execute_write.
The local server runs with sitegpt mcp over stdio and uses an API token. That makes it the option for a sandbox or container where a browser approval is impractical.
Claude is the confirmed MCP client, and the Claude setup guide walks through it. The agents page describes what an assistant can operate end to end.
What changes in a HIPAA workspace?
The integration surface narrows. Three terms first: HIPAA is the Health Insurance Portability and Accountability Act, PHI is protected health information, and a BAA is a Business Associate Agreement, the contract a vendor signs before it handles PHI.
A SiteGPT BAA is available on the Enterprise plan only. It is not offered on Starter, Growth, or Scale. In a workspace covered by one, the API behaves differently:
| Surface | Behavior in a HIPAA workspace |
|---|---|
| Cloud file connectors | API v2, the CLI, the SDKs, and MCP return 403 HIPAA_CONNECTORS_DISABLED. Add content with links, file uploads, and text instead. |
| MCP servers | Conversations, leads, and escalations return 403 HIPAA_AI_ASSISTANTS_DISABLED. Settings, analytics, and appearance tools still work. |
| Webhooks | Bodies carry the event and IDs. Message text, sources, and contact details are removed. |
| Training content | Must stay free of PHI. SiteGPT does not scan for it, so that review is yours. |
Plan for this before you design the ticketing flow. A webhook handler in a HIPAA workspace receives a threadId and a dashboard link, and an agent opens the conversation in the dashboard to read it. The HIPAA program page and the workspace documentation are the canonical sources.
What does a production rollout look like?
Work through these steps in order. Each one is small, and the first call needs no credential at all.
- Call
GET /api/v2/healthfrom the network that will host the integration. - Create one token per integration, with the narrowest scopes, specific chatbots, and an expiry.
- Store each token in a secret manager and record its rotation date.
- Add content through the knowledge endpoints and set a sync frequency.
- Send a test message, store the
threadId, and send a follow-up. - Set webhook URLs with a random token each, and verify the header in the handler.
- Schedule a reconciliation job that reads escalations and leads through the API.
- Add the CLI sync and smoke test to the pipeline.
- Review the token list on the Agents page and revoke anything unused.
Frequently asked questions
Which SiteGPT plan includes API access? API v2, the SDKs, the CLI, and the MCP server need the Growth plan or above. Growth is $129 per month billed monthly, or $79 per month billed yearly. Starter does not include API access. Webhooks are on Scale and above, or available with the webhook add-on.
How does SiteGPT API authentication work?
API v2 accepts an API token as a bearer credential in the Authorization header. Tokens start with sgpt_ and come from the Agents page, device login, or POST /api/v2/tokens. Each token carries scopes, can be restricted to specific chatbots, and expires after 1 to 365 days.
How does a SiteGPT chatbot keep context across API calls?
The conversation is stored on the SiteGPT side under a threadId. The first message starts a conversation and returns the id. Each follow-up goes to the conversation endpoint with only the new message.
Are SiteGPT webhooks signed?
No. Each webhook URL has its own token, sent in the X-WEBHOOK-TOKEN header, and comparing that header is the only origin check. Deliveries are sent once with no retry, so add a reconciliation job that reads from API v2.
Does the SiteGPT API have rate limits?
The API conventions page states that there is no published per-request rate limit and no rate-limit headers. A 429 means a plan quota is used up. Retrying it in a loop does not help.
Can the SiteGPT CLI run in a CI/CD pipeline?
Yes. Set SITEGPT_API_TOKEN as a pipeline secret and no interactive login is needed. Every command accepts --json and exits non-zero on failure, and knowledge commands accept --wait.
Does the API work in a HIPAA workspace? It works with narrower behavior. A BAA is available on the Enterprise plan only. Cloud file connectors are refused, the MCP servers do not return conversations or leads, and webhook bodies carry IDs without message text.
Is there an official SiteGPT SDK?
Yes. SiteGPT publishes a TypeScript SDK (@sitegpt/sdk), a Python SDK (sitegpt), and a Go SDK. All three call API v2 with the same sgpt_ tokens.
Sources
- API v2 getting started for the base URL, the first four calls, and the plan requirement
- API conventions for the response envelope, error codes, delete confirmation, and rate-limit statement
- Authentication reference for access levels, scopes, token expiry, and device login
- Webhooks reference for the four events, the token header, and delivery behavior
- MCP documentation for the remote and local servers and HIPAA workspace behavior
- Security and data handling for encryption, SOC 2 Type II, and hosting region
- OpenAPI document for endpoint paths and request schemas
- SiteGPT pricing for plan rates and API access by plan
- The
healthand401responses were captured from the live API on 2026-10-13