For the complete documentation index, see llms.txt
Skip to main content

Migrate from API v1 to v2

API v2 replaces v1 as the documented, actively developed API. v1 keeps working for existing integrations, but it no longer receives new features and is scheduled for retirement in January 2027.

This guide lists the changes required to move a v1 integration to v2 before that date.

The v1 reference remains available until v1 is retired.

What stays the same

  • Authentication. Send Authorization: Api-Key <your-api-key>, exactly as in v1. Existing API keys keep working; you don't need to re-issue them.
  • Base URL. https://app.biel.ai.
  • Public project access. Read operations on public projects still work without an API key.
  • Search. Request parameters and the response shape of the search endpoint are unchanged; only the base path changes.

Endpoint mapping

Every v1 endpoint has a direct v2 replacement.

v1 endpointv2 endpoint
POST /api/v1/chats/POST /api/v2/projects/{slug}/chats/
GET /api/v1/projects/{slug}/GET /api/v2/projects/{slug}/
GET /api/v1/projects/{slug}/search/GET /api/v2/projects/{slug}/search/
GET /api/v1/projects/{slug}/sources/GET /api/v2/projects/{slug}/sources/
POST /api/v1/projects/{slug}/sources/POST /api/v2/projects/{slug}/sources/
DELETE /api/v1/projects/{slug}/sources/{source_uuid}/DELETE /api/v2/projects/{slug}/sources/{source_uuid}/
POST /api/v1/projects/{slug}/sources/sync/POST /api/v2/projects/{slug}/sync/

Permission renames

v2 renames API key permissions to a consistent <resource>_<action> scheme.

v1 permissionv2 permission
project_readprojects_read
project_searchsearch
project_sources_readsources_read
project_sources_createsources_create
project_sources_deletesources_delete
project_syncsync_create
chat_createchats_create

Keys created before v2 may carry the legacy names. They remain valid as aliases of their v2 equivalents, so no key rotation is needed.

Breaking changes

Send a message: project moved to the path

Sending a message now happens under the project, at POST /api/v2/projects/{slug}/chats/. Remove project_slug from the request body and put the slug in the URL instead. The rest of the body (message, chat_uuid, url, email, think_mode, metadata) and the 200/201 response are unchanged.

v1
curl -X POST https://app.biel.ai/api/v1/chats/ \
-H "Authorization: Api-Key $BIEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"project_slug": "my-project", "message": "How do I install the widget?"}'
v2
curl -X POST https://app.biel.ai/api/v2/projects/my-project/chats/ \
-H "Authorization: Api-Key $BIEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "How do I install the widget?"}'

Get project: settings grouped under config

The v1 response returned all settings as top-level fields. In v2, feature settings are grouped under a config object, and the response adds identity and lifecycle fields (slug, uuid, name, is_private, last_sync, created_at, updated_at).

v1 fieldv2 field
initial_messageconfig.chat.initial_message
suggested_questionsconfig.chat.suggested_questions
think_modeconfig.chat.think_mode
filtersconfig.search.filters
mcp_enabledconfig.mcp.enabled
mcp_server_nameconfig.mcp.server_name
mcp_metadata_tagconfig.mcp.metadata_tag
whitelabelwhitelabel (unchanged)

uuid is the public project identifier that the embeddable widget takes in its project attribute.

Get project: new settings with no v1 equivalent

The config object also carries settings that v1 did not have. A v1 integration that reads or writes project settings will encounter them for the first time in v2.

v2 fieldDescription
config.prompt.use_defaultWhether the built-in system prompt is used.
config.prompt.versionVersion of the built-in assistant prompt.
config.prompt.extendCustom instructions appended to the built-in prompt, or used on their own when use_default is false.
config.chat.actionsCall-to-action buttons the chat widget renders alongside answers. Each has name, button_text, and url.

config.chat.actions is read-only. Read-only fields are returned in responses but rejected in requests, so an integration that reads a project and sends the whole object back to update it gets a validation error. Send only the fields you want to change.

Sync: new path and asynchronous response

Sync is its own resource in v2, no longer nested under sources.

  • The endpoint moves from POST /api/v1/projects/{slug}/sources/sync/ to POST /api/v2/projects/{slug}/sync/.
  • v2 returns 202 Accepted with a sync run summary (uuid, status, timestamps) instead of the v1 200 with a message. Poll GET /api/v2/projects/{slug}/sync/ or read the project's last_sync field to track completion.
  • Calling the endpoint while a sync is already running cancels the in-progress run and starts a fresh one. v1 returned 400 in that case. If your integration relied on the 400 to avoid duplicate syncs, check the sync status before triggering a new run.

Add source: 201 status and typed sources

List sources: paginated response and new source types

  • v1 returned a bare JSON array of sources. v2 returns a paginated object, so read the sources from results instead of iterating the response directly.

    FieldDescription
    countTotal number of sources matching the query.
    nextURL of the next page, or null on the last page.
    previousURL of the previous page, or null on the first page.
    resultsThe sources on this page.

    Page size defaults to 20 and is capped at 100. Use the limit and offset query parameters to page through a project with more sources than that, or follow next until it is null.

  • Source objects now include created_at, and the type enum adds repository, openapi, and confluence. If your integration validates type against a fixed list, update it.

New in v2

These capabilities have no v1 equivalent:

  • Projects: create, list, update, and delete projects.
  • Chats: list chats, retrieve a full conversation, delete a conversation, and submit message feedback.
  • Sources: add GitHub repositories, OpenAPI specifications, and Confluence spaces, including private ones via a JSON body with credentials.
  • Sync: poll sync runs and read the event log for a run.
  • Analytics: read aggregate chat, search, MCP, and insights metrics.
  • Teams: manage the team that owns the API key, including members and invitations. The team response also reports subscription status and plan (subscription) and trial state (trial).
  • Search click tracking: report result clicks to improve search analytics.
  • OpenAPI validation: check an OpenAPI specification against the same checks Biel runs when it indexes it, so you can catch a spec that would fail to parse before the next sync.

See the API v2 reference for details.