For AI agents: markdown of this page — /docs-content-en/partner-connect.md documentation index — /llms.txt
Partner Connect
Connecting external services to Bitrix24: your application asks the user for permission to access their Bitrix24 account and receives a Vibecode API key for subsequent calls. The flow is built on the Authorization Code scheme — the same one used by OAuth providers like Google or GitHub.
Base URL: https://vibecode.bitrix24.com/v1 | Authorization: the partner's client_id + client_secret | Key scopes: requested on the consent page
Contents
- When to use
- How it works
- Endpoint reference
- Full scenario — an Express handler end to end
GET /v1/connect/authorize— flow start, redirect to consentPOST /v1/connect/token— exchanging the code for an API key- Using the API key
- Available scopes
- Key lifetime and revocation
- Security
- Partner registration
- See also
When to use
The scenario is an external SaaS product that integrates with your clients' Bitrix24 accounts: CRM analytics, ERP synchronization, a chat assistant, a landing page builder. A "Connect Bitrix24" button on your site launches the flow: the user selects a Bitrix24 account and confirms the scopes, your server receives a permanent API key and works with the Bitrix24 account on behalf of the user.
If you are building an application that is installed inside a Bitrix24 account and works only with it, use a regular API key, see Authorization and keys.
How it works
Your application → [1. Redirect] → Vibecode Consent Page → [2. Consent]
↑ ↓
└──── [4. API key] ←── [3. Code → redirect_uri] ──────────┘
- Redirect — you send the user to
/v1/connect/authorizewithclient_id,redirect_uri,state, and a list of scopes. - Consent — the user sees a Vibecode page, selects a Bitrix24 account, and confirms or declines the requested scopes.
- Code — after approval the user returns to
redirect_uriwith thecodeandstateparameters. On decline —redirect_uri?error=access_denied&state=.... - Exchange — the partner's server sends
POST /v1/connect/tokenand receives an API key.
Endpoint reference
| Method | Path | Description |
|---|---|---|
| GET | /v1/connect/authorize |
Flow start: redirect to the consent page |
| POST | /v1/connect/token |
Exchange a one-time code for a permanent API key |
Full scenario
An example Express handler that walks the user through both endpoints end to end. Before launching, place the client_id and client_secret, issued by the Alaio Vibecode team, into environment variables, and register the redirect_uri with the partner.
import express from 'express'
import crypto from 'node:crypto'
const app = express()
const sessions = new Map() // in production — Redis or a DB
const CLIENT_ID = process.env.PARTNER_CLIENT_ID
const CLIENT_SECRET = process.env.PARTNER_CLIENT_SECRET
const REDIRECT_URI = 'https://yourapp.com/callback'
// 1. The "Connect Bitrix24" button leads here
app.get('/connect', (req, res) => {
const state = crypto.randomBytes(16).toString('hex')
sessions.set(state, { userId: req.user.id, createdAt: Date.now() })
const params = new URLSearchParams({
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
scopes: 'crm,task',
state,
})
res.redirect(`https://vibecode.bitrix24.com/v1/connect/authorize?${params}`)
})
// 2. Vibecode returns the user here after consent or decline
app.get('/callback', async (req, res) => {
const { code, state, error } = req.query
const session = sessions.get(state)
if (!session) return res.status(400).send('Unknown state')
sessions.delete(state)
if (error === 'access_denied') {
return res.redirect('/dashboard?connect=denied')
}
// 3. Exchange the code for an API key — a server-side request with client_secret
const tokenRes = await fetch('https://vibecode.bitrix24.com/v1/connect/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
code,
redirect_uri: REDIRECT_URI,
}),
})
const data = await tokenRes.json()
if (!data.success) {
return res.status(400).send(`Exchange error: ${data.error.code}`)
}
// 4. Store the binding: our service user ↔ Bitrix24 portal
await db.connections.upsert({
userId: session.userId,
portalDomain: data.portal.domain,
portalName: data.portal.name,
apiKey: encrypt(data.api_key), // secret, encrypt before storing
scopes: data.scopes,
})
res.redirect('/dashboard?connect=ok')
})
// 5. From here on we use the stored key for calls on behalf of the user
async function listDeals(userId) {
const connection = await db.connections.findByUserId(userId)
const apiKey = decrypt(connection.apiKey)
const res = await fetch('https://vibecode.bitrix24.com/v1/deals?limit=10', {
headers: { 'X-Api-Key': apiKey },
})
return res.json()
}
Key points of the scenario:
stateis generated on the server and verified on return — without this check an attacker could slip the user someone else's code.client_secretis kept only on the server and never reaches the browser.- The API key is encrypted before being written to the DB and decrypted only at the moment of a call.
- On
error=access_deniedthe user sees a clear message rather than an exchange error page.
GET /v1/connect/authorize
Redirects the user to the Alaio Vibecode consent page.
Query parameters:
| Parameter | Type | Req. | Description |
|---|---|---|---|
client_id |
string | yes | Partner identifier, issued by the Alaio Vibecode team |
redirect_uri |
string | yes | Callback URL. Must match one of those registered with the partner |
state |
string | yes | An arbitrary string that will be returned along with the code. CSRF protection |
scopes |
string | no | Comma-separated list of scopes: crm,task,im. If not passed — the default scopes from the partner settings apply |
Example URL:
https://vibecode.bitrix24.com/v1/connect/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=https://yourapp.com/callback&scopes=crm,task&state=abc123random
Successful redirect after approval:
https://yourapp.com/callback?code=AUTH_CODE_HERE&state=abc123random
Redirect on decline by the user on the consent page:
https://yourapp.com/callback?error=access_denied&state=abc123random
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_REQUEST |
One of client_id, redirect_uri, state was not passed |
| 400 | INVALID_CLIENT |
client_id is not registered or the partner is disabled |
| 400 | INVALID_REDIRECT_URI |
redirect_uri does not match any of those registered with the partner |
| 400 | INVALID_SCOPE |
One or more scopes are not in the list allowed for Bitrix24 |
The full reference of general API errors — Errors.
POST /v1/connect/token
Exchanges a one-time authorization code for a permanent API key. Accepts application/json and application/x-www-form-urlencoded.
Request fields (body):
| Field | Type | Req. | Description |
|---|---|---|---|
client_id |
string | yes | Partner identifier |
client_secret |
string | yes | Partner secret. Pass only from the server side |
code |
string | yes | The code from the code parameter of the redirect |
redirect_uri |
string | yes | The same redirect_uri that was passed to /v1/connect/authorize |
Examples
curl
curl -X POST https://vibecode.bitrix24.com/v1/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d code=RECEIVED_CODE \
-d redirect_uri=https://yourapp.com/callback
JavaScript
const res = await fetch('https://vibecode.bitrix24.com/v1/connect/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
code: receivedCode,
redirect_uri: 'https://yourapp.com/callback',
}),
})
const data = await res.json()
// data.api_key — permanent Vibecode API key
// data.portal — the portal selected by the user
// data.scopes — the confirmed scopes
// data.user — the user who granted access
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | true on a successful exchange |
api_key |
string | Vibecode API key in the vibe_app_... format. Pass it in the X-Api-Key header on subsequent calls |
portal.domain |
string | Bitrix24 account domain, for example example.bitrix24.com |
portal.name |
string | Bitrix24 account name |
scopes |
string[] | List of scopes the user confirmed. May be shorter than requested if the user removed some |
user.name |
string | Name of the user who granted access |
user.email |
string | The user's email |
Response example
{
"success": true,
"api_key": "vibe_app_...",
"portal": {
"domain": "example.bitrix24.com",
"name": "My company"
},
"scopes": ["crm", "task"],
"user": {
"name": "John Smith",
"email": "john@example.com"
}
}
Error response example
400 — a required parameter is missing:
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "Missing required parameters"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_REQUEST |
One of client_id, client_secret, code, redirect_uri was not passed |
| 400 | INVALID_CODE |
The code does not exist, has expired (5 minutes), has already been used, or redirect_uri differs from the one passed to /v1/connect/authorize |
| 401 | INVALID_CLIENT |
client_id is unknown or client_secret does not match |
| 403 | PARTNER_DISABLED |
The partner account is suspended |
The full reference of general API errors — Errors.
Using the API key
The received key is of type APP and works like a standard Vibecode API key. Pass it in the X-Api-Key header:
curl -H "X-Api-Key: vibe_app_..." \
https://vibecode.bitrix24.com/v1/deals
The same key can be used with any Vibecode API endpoint within the confirmed scopes: deal lists, batch requests, aggregation, and so on.
Unlike a key created in the cabinet, a partner key is not automatically granted the platform scopes vibe:ai (AI router) and vibe:search (web search) — it carries exactly the permissions the user confirmed on the consent screen. Calls to the AI router (/v1/chat/completions) and web search (/v1/search) through a partner key therefore return 403 by default.
The partner key works with a single X-Api-Key header and does not require Authorization: Bearer <session_token>. This distinguishes it from OAuth application keys from the Vibecode catalog with the same vibe_app_... prefix — there a user session is mandatory.
Available scopes
When calling /v1/connect/authorize, pass the same scopes you would when creating a standard API key in a Bitrix24 account. On the consent page the user sees the list and can remove individual items — the final set arrives in the scopes field of the /v1/connect/token response.
The full list of supported values (32 scopes: crm, task, tasks, im, imbot, imopenlines, call, telephony, bizproc, calendar, timeman, catalog, sale, lists, disk, entity, user, user_basic, user_brief, user.userfield, department, landing, documentgenerator, sign.b2e, sonet_group, log, vote, ai_admin, biconnector, booking, delivery, pay_system, main, placement, userfieldtype) is described in the Authorization and keys section.
Key lifetime and revocation
- The authorization code (
code) is valid for 5 minutes and is one-time. After the exchange via/v1/connect/token, a repeat call with the same code will returnINVALID_CODE. - The consent state (the internal state of the consent page) lives 10 minutes — if the user does not confirm within that time, the link has to be issued again.
- The API key has no expiration. It works until:
- the user revokes access in the Bitrix24 account (on the granted-permissions management page in their account),
- or the Alaio Vibecode team suspends the partner application.
When a key is revoked, all requests with it return 401 KEY_INACTIVE. If the key is deleted or unknown — 401 INVALID_API_KEY. The partner must handle both codes correctly and prompt the user to re-authorize.
Security
- State parameter — generate a cryptographically strong random string for each request and verify it on return to
redirect_uri. Protects against CSRF. client_secret— server only. Never pass the secret to a browser, mobile app, or client-side code. The code-for-key exchange is performed only by a server-side request.- Key storage. The API key is a secret that grants access to the user's data. Store it encrypted, restrict access to the connection string, do not log it.
redirect_uribinding. The value in/v1/connect/authorizeand/v1/connect/tokenmust match character for character — a mismatch will lead toINVALID_CODE.
Partner registration
Self-service registration is not yet available — client_id and client_secret are issued by the Alaio Vibecode team after reviewing the application. To submit a request, write to partners@bitrix24.com.
In the request specify:
- the name and a short description of the application,
- the use case,
- the list of requested scopes,
- one or more
redirect_urivalues you will use.
See also
- Authorization and keys — general rules for working with Vibecode API keys, key types (including OAuth applications), the list of scopes
- Management keys — programmatic key creation for your own Bitrix24 account
- API errors — the general error-code reference