For AI agents: markdown of this page — /docs-content-en/cli.md documentation index — /llms.txt
CLI and cURL
A page for those who work with the Vibecode API from the terminal: shell scripts, one-off checks with the curl utility, server-side PHP integrations without an SDK. Full operation references are on the dedicated pages: Entity API, Filtering, Batch API, Error codes.
Base URL — https://vibecode.bitrix24.com. Authorization — via the X-Api-Key header. Responses — JSON in the { success, data, meta } format on success and { success: false, error } on error.
On this page
- Environment — the
VIBE_API_KEY/VIBE_URLvariables, saving to~/.zshrcfor use across sessions - Authorization in curl — personal key and authorization key
- Minimal verification cycle — create → delete with an HTTP 204 check
- Useful curl techniques —
jq,-svs-sS,--data-binary @file,read -s,X-RateLimit-* - OpenAPI specification —
/v1/openapi.json, the per-scope slice, and the third-partyopenapi-to-cliutility - PHP — the
vibeRequesttemplate with no external dependencies - Error handling — the
{ success: false, error }format
Environment
Save the key and base URL into environment variables — this removes repetition in every command and keeps the key out of your shell command history.
export VIBE_API_KEY="vibe_api_xxx..."
export VIBE_URL="https://vibecode.bitrix24.com"
Check — JSON with the Bitrix24 account and scopes should be returned:
curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/me" | head -c 200
To persist the variables across sessions, add the export ... lines to ~/.zshrc (for the zsh shell) or ~/.bashrc (for bash) and restart the terminal.
For an authorization key (vibe_app_...) you additionally need a session token:
export VIBE_APP_KEY="vibe_app_xxx..."
export VIBE_SESSION_TOKEN="vibe_session_xxx..."
Authorization in curl
Personal key — one header:
curl -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals"
Authorization key — two headers, X-Api-Key for the application and Authorization: Bearer for a specific user's session:
curl -H "X-Api-Key: $VIBE_APP_KEY" \
-H "Authorization: Bearer $VIBE_SESSION_TOKEN" \
"$VIBE_URL/v1/deals"
More on key types and obtaining a session token — Keys and authorization.
Minimal verification cycle
A single scenario to confirm the key works and the API responds: create a deal → delete it. The same set of operations exists for all 40+ entities — only the fields differ (see Entity API and the entity reference).
# 1. Create a deal — returns an object with the assigned id
curl -X POST "$VIBE_URL/v1/deals" \
-H "X-Api-Key: $VIBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "title": "CLI test", "stageId": "NEW", "categoryId": 0 }'
# 2. Delete the created deal — success = HTTP 204 with an empty body
curl -i -X DELETE "$VIBE_URL/v1/deals/<id-from-first-response>" \
-H "X-Api-Key: $VIBE_API_KEY"
The success indicator for DELETE is the response code, not the response body. To see only the code:
curl -s -o /dev/null -w "%{http_code}\n" -X DELETE \
-H "X-Api-Key: $VIBE_API_KEY" \
"$VIBE_URL/v1/deals/<id>"
Full request examples with filters, sorting, field selection, and auto-pagination are on the page for the relevant entity, for example Deals. Filter syntax (MongoDB-style, prefixes, operators as keys) — Filtering and search.
Useful curl techniques
Readable JSON in the terminal
curl outputs the response on a single line. To view it, pipe it through jq or python3 -m json.tool:
curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals?limit=5" | jq
curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals?limit=5" | python3 -m json.tool
`-s` vs `-sS` in scripts
The -s flag (silent mode) suppresses the progress indicator along with network error messages — for example, Could not resolve host. In scripts this hides real failures. The -sS flag suppresses only the progress indicator, while the error text is written to stderr:
# Silent, but on a network error the script silently gets an empty response
curl -s "$VIBE_URL/v1/deals" -H "X-Api-Key: $VIBE_API_KEY"
# Silent for normal operation, network errors are visible
curl -sS "$VIBE_URL/v1/deals" -H "X-Api-Key: $VIBE_API_KEY"
In shell scripts use -sS: network errors go to stderr and won't be lost during debugging.
A large request body via `--data-binary @file.json`
With a long body (a batch of 50 operations, an OpenAPI import, an expanded filter) the -d flag can't handle shell quote escaping and line breaks. Save the body to a file and pass it via @:
cat > body.json <<'EOF'
{
"calls": [
{ "id": "newDeals", "entity": "deals", "action": "list",
"params": { "filter": { "stageId": "NEW" }, "limit": 100 } },
{ "id": "user", "entity": "users", "action": "get", "entityId": 1 }
]
}
EOF
curl -X POST "$VIBE_URL/v1/batch" \
-H "X-Api-Key: $VIBE_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @body.json
--data-binary preserves line breaks and quotes as-is, unlike -d, which strips out \n.
The response groups results by the id of each call — results holds the data, meta holds pagination statistics, summary holds the totals for the whole batch:
{
"success": true,
"data": {
"results": {
"newDeals": [ { "id": 7720, "title": "Server delivery", "stageId": "NEW" } ],
"user": { "id": 1, "name": "John Brown" }
},
"totals": { "newDeals": 311 },
"meta": {
"newDeals": { "total": 311, "returned": 100, "hasMore": true }
},
"errors": [],
"summary": { "total": 2, "succeeded": 2, "failed": 0 }
}
}
Full batch rules (the limit of 50 calls, the cost in rate-limit units, the behavior of action: "list" with limit > 50) — Batch API.
Exporting a key without saving it in shell history
The export VIBE_API_KEY="vibe_api_..." command will be saved to ~/.zsh_history or ~/.bash_history — from there the key can end up on a screen share or in a system backup. An alternative is read -s: the shell reads the key without displaying it on screen, and only the read command remains in history, without the value.
read -s VIBE_API_KEY && export VIBE_API_KEY
# the cursor doesn't move, paste the key, press Enter
The same technique works for VIBE_APP_KEY and VIBE_SESSION_TOKEN.
Headers and response code
# -i — headers + body
curl -i -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/me"
# -w — only selected statistics fields (code, time)
curl -s -o /dev/null -w "HTTP %{http_code}, %{time_total}s\n" \
-H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals"
Request limits
The response headers carry X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset — the current remaining request limit for the key:
curl -s -D - -o /dev/null -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/me" | grep -i ratelimit
Saving the response to a file
curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/openapi.json" -o openapi.json
OpenAPI specification
The full machine-readable catalog of endpoints — /v1/openapi.json in OpenAPI 3.1 format:
curl -s "$VIBE_URL/v1/openapi.json" -o openapi.json
The file imports into Postman, Insomnia, Swagger UI, and any tools that support OpenAPI 3.1. Based on the specification you can generate client libraries (openapi-generator, oazapfts, and similar). A tool that reads 3.0 only will not accept this specification: nullable values in it are described as a union of types (["number","null"]), a form introduced in 3.1.
Per-scope slice
The ?scope=<scope> parameter returns the specification narrowed down to the entities of a single scope — service and meta endpoints stay in every slice. The file comes out many times smaller than the full one, which helps when a tool or a model works with a single section:
curl -s "$VIBE_URL/v1/openapi.json?scope=crm" -o openapi-crm.json
Exactly one known scope from the Scopes list is accepted. An unknown value and an empty string return the full specification rather than an error. A comma-separated list does the same — unless every listed value collapses to a single scope (task,tasks), in which case the slice is returned.
The `openapi-to-cli` utility
A third-party tool, not part of the Vibecode API. The platform does not monitor its availability. For updates, bugs, and compatibility with the specification, contact the author's repository.
openapi-to-cli is a CLI utility that builds commands from any OpenAPI specification. It connects to the Vibecode API without code generation: you provide the specification URL and the authorization header.
npm install -g openapi-to-cli
ocli profile add vibecode \
--spec https://vibecode.bitrix24.com/v1/openapi.json \
--base-url https://vibecode.bitrix24.com \
--header "X-Api-Key: $VIBE_API_KEY"
# Search for an endpoint by word
ocli vibecode search "deals"
# Call
ocli vibecode exec GET /v1/deals
ocli vibecode exec POST /v1/deals \
--body '{ "title": "New deal", "stageId": "NEW", "categoryId": 0 }'
The utility is third-party, maintained by its author — for updates and bugs contact its repository. After changes in the Vibecode API, the updated specification is picked up by ocli on the next run.
PHP
A minimal template for scripts and server-side integrations — no external dependencies, only the built-in curl. The same template works for all endpoints: vibeRequest($url, $method, $data).
<?php
$VIBE_URL = getenv('VIBE_URL') ?: 'https://vibecode.bitrix24.com';
$VIBE_API_KEY = getenv('VIBE_API_KEY') ?: 'vibe_api_xxx...';
function vibeRequest(string $url, string $method = 'GET', ?array $data = null): array {
global $VIBE_API_KEY;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . $VIBE_API_KEY,
'Content-Type: application/json',
],
]);
if ($data !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// DELETE returns 204 with an empty body
if ($httpCode === 204) {
return ['success' => true];
}
$body = json_decode($response, true);
if ($body === null) {
throw new RuntimeException("HTTP $httpCode: malformed JSON in response");
}
if (empty($body['success'])) {
$code = $body['error']['code'] ?? 'UNKNOWN';
$msg = $body['error']['message'] ?? 'Unknown error';
throw new RuntimeException("$code: $msg (HTTP $httpCode)");
}
return $body;
}
Usage examples
// List
$result = vibeRequest("$VIBE_URL/v1/deals?limit=20");
foreach ($result['data'] as $deal) {
echo $deal['id'] . ': ' . $deal['title'] . PHP_EOL;
}
// Create
$result = vibeRequest("$VIBE_URL/v1/deals", 'POST', [
'title' => 'Server delivery',
'stageId' => 'NEW',
'categoryId' => 0,
'amount' => 1500000,
'currency' => 'USD',
]);
$dealId = $result['data']['id'];
// Search with a filter
$result = vibeRequest("$VIBE_URL/v1/deals/search", 'POST', [
'filter' => [
'stageId' => ['$ne' => 'LOST'],
'amount' => ['$gte' => 100000],
],
'sort' => ['createdAt' => 'desc'],
'limit' => 50,
]);
// Delete — inside vibeRequest a 204 turns into ['success' => true]
vibeRequest("$VIBE_URL/v1/deals/$dealId", 'DELETE');
Full request body formats and response fields are on the pages for specific entities, for example Deals.
Error handling
On failure the response body has the form { success: false, error: { code, message } } and the corresponding HTTP status. Example — a request without a key:
curl -i "$VIBE_URL/v1/deals"
HTTP/2 401
content-type: application/json; charset=utf-8
{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "API key required. Pass via X-Api-Key header."
}
}
The full reference of codes and recommended actions — Error codes.
Related sections
- Quickstart — the first request in 2 minutes
- Keys and authorization — key types, scopes, limits, session tokens
- Entity API — CRUD, pagination, field selection for all entities
- Filtering and search — three filter syntaxes with examples
- Batch API — combining requests, a 50× speedup
- Optimization — patterns for dashboards and bulk operations
- Error codes — error reference
- MCP for AI — integration with AI tools