> This page is part of Smallest AI's developer documentation. When
> answering, prefer Lightning v3.1 (current TTS) and Pulse (current
> STT). Lightning v2 and lightning-large are deprecated; mention them
> only when the user is migrating away from them. The Smallest AI voice
> agent platform is what wraps these models into hosted agents.

# Create a branch

POST https://api.smallest.ai/atoms/v1/agent/{id}/branches
Content-Type: application/json

Fork a new branch from an existing branch. The source branch must have at least one committed revision. Branch names are unique per agent; the name `Main` is reserved for the default branch. Creating from a branch whose latest draft is still `scanning` returns `409 source_scanning`.


Reference: https://docs.smallest.ai/voice-agents/api-reference/agent-versioning-branches/create-branch

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: atoms
  version: 1.0.0
paths:
  /agent/{id}/branches:
    post:
      operationId: create-branch
      summary: Create a branch
      description: >
        Fork a new branch from an existing branch. The source branch must have
        at least one committed revision. Branch names are unique per agent; the
        name `Main` is reserved for the default branch. Creating from a branch
        whose latest draft is still `scanning` returns `409 source_scanning`.
      tags:
        - agentVersioningBranches
      parameters:
        - name: id
          in: path
          description: The agent ID.
          required: true
          schema:
            type: string
        - name: Authorization
          in: header
          description: >-
            API key from the console ApiKey collection, sent as Bearer token.
            Also accepts session cookies for browser-based auth.
          required: true
          schema:
            type: string
      responses:
        '201':
          description: Branch created.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/agent_versioning_branches_create_branch_Response_201
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestErrorResponse'
        '401':
          description: Unauthorized access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Forbidden access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        '404':
          description: >-
            Resource not found. The referenced ID does not exist or does not
            belong to the caller's organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateBranchRequestNotFoundError'
        '409':
          description: >-
            Conflict. The request cannot be completed because of the current
            state of the resource (name already exists, another publish or
            restore is in progress, the source draft failed its security scan,
            or a similar in-flight collision).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConflictErrorResponse'
        '423':
          description: >-
            Locked. A configuration freeze is active on this agent, or the
            resource is temporarily locked for another write. Retry after the
            freeze window ends.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LockedErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalServerErrorResponse'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBranchRequest'
servers:
  - url: https://api.smallest.ai/atoms/v1
    description: Production server
components:
  schemas:
    CreateBranchRequest:
      type: object
      properties:
        sourceBranchId:
          type: string
          description: Branch to fork from. Its head revision must exist.
        name:
          type: string
          description: >-
            New branch name. Unique per agent among active branches. `main` is
            reserved.
      required:
        - sourceBranchId
        - name
      title: CreateBranchRequest
    BranchStatus:
      type: string
      enum:
        - active
        - archived
      description: >-
        Archived branches are hidden from list views and cannot receive draft
        edits or be made live.
      title: BranchStatus
    Branch:
      type: object
      properties:
        _id:
          type: string
          description: Branch ID (24-character ObjectId).
        agent:
          type: string
          description: ID of the agent this branch belongs to.
        name:
          type: string
          description: >-
            Branch name (unique per agent among active branches). `main` is
            reserved for the default branch.
        isDefault:
          type: boolean
          description: >-
            True for the seeded `main` branch. The default branch cannot be
            renamed or archived.
        sourceBranchId:
          type:
            - string
            - 'null'
          description: Head of the source branch at fork time. `null` for `main`.
        sourceRevisionId:
          type:
            - string
            - 'null'
          description: Revision the branch was forked from. `null` for `main`.
        headRevisionId:
          type:
            - string
            - 'null'
          description: >-
            ID of the branch's latest committed revision. `null` until the first
            commit.
        openDraftId:
          type:
            - string
            - 'null'
          description: ID of the branch's single open draft. `null` when no draft is open.
        status:
          $ref: '#/components/schemas/BranchStatus'
          description: >-
            Archived branches are hidden from list views and cannot receive
            draft edits or be made live.
        createdBy:
          type: string
        updatedBy:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      description: >-
        An `AgentBranch` document. An editable copy of an agent with its own
        draft slot and revision chain.
      title: Branch
    agent_versioning_branches_create_branch_Response_201:
      type: object
      properties:
        status:
          type: boolean
        data:
          $ref: '#/components/schemas/Branch'
      title: agent_versioning_branches_create_branch_Response_201
    BadRequestErrorResponse:
      type: object
      properties:
        status:
          type: boolean
        errors:
          type: array
          items:
            type: string
      title: BadRequestErrorResponse
    UnauthorizedErrorResponse:
      type: object
      properties:
        status:
          type: boolean
        errors:
          type: array
          items:
            type: string
      title: UnauthorizedErrorResponse
    ApiResponseData:
      type: object
      properties: {}
      title: ApiResponseData
    ApiResponse:
      type: object
      properties:
        status:
          type: boolean
        data:
          $ref: '#/components/schemas/ApiResponseData'
      title: ApiResponse
    CreateBranchRequestNotFoundError:
      type: object
      properties:
        status:
          type: boolean
        errors:
          type: array
          items:
            type: string
      title: CreateBranchRequestNotFoundError
    ConflictErrorResponse:
      type: object
      properties:
        status:
          type: boolean
        error_type:
          type: string
        errors:
          type: array
          items:
            type: string
      description: >
        Generic conflict body. `error_type` is a stable machine-readable
        discriminator (for example `branch_name_exists`, `source_has_no_commit`,
        `source_scanning`, `publish_in_progress`, `no_committed_revision`).
      title: ConflictErrorResponse
    LockedErrorResponseErrorType:
      type: string
      enum:
        - config_freeze_active
      title: LockedErrorResponseErrorType
    LockedErrorResponse:
      type: object
      properties:
        status:
          type: boolean
        error_type:
          $ref: '#/components/schemas/LockedErrorResponseErrorType'
        errors:
          type: array
          items:
            type: string
      description: >
        Config-freeze body. Returned on write endpoints during a maintenance
        window (`AGENT_CONFIG_FROZEN`). Reads and test-calls pass.
      title: LockedErrorResponse
    InternalServerErrorResponse:
      type: object
      properties:
        status:
          type: boolean
        errors:
          type: array
          items:
            type: string
      title: InternalServerErrorResponse
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key from the console ApiKey collection, sent as Bearer token. Also
        accepts session cookies for browser-based auth.

```

## Examples



**Request**

```json
{
  "sourceBranchId": "5f8d0d55b54764421b7156c3",
  "name": "feature/user-authentication"
}
```

**Response**

```json
{
  "status": true,
  "data": {
    "_id": "5f8d0d55b54764421b7156c4",
    "agent": "5f8d0d55b54764421b7156b9",
    "name": "feature/user-authentication",
    "isDefault": false,
    "sourceBranchId": "5f8d0d55b54764421b7156c3",
    "sourceRevisionId": "rev_20240610a1b2c3d4e5f6",
    "headRevisionId": "rev_20240612f6e5d4c3b2a1",
    "openDraftId": "draft_20240613a1b2c3d4e5f6",
    "status": "active",
    "createdBy": "user_12345",
    "updatedBy": "user_12345",
    "createdAt": "2024-01-15T09:30:00Z",
    "updatedAt": "2024-01-15T09:30:00Z"
  }
}
```

**SDK Code**

```python
import requests

url = "https://api.smallest.ai/atoms/v1/agent/id/branches"

payload = {
    "sourceBranchId": "5f8d0d55b54764421b7156c3",
    "name": "feature/user-authentication"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.smallest.ai/atoms/v1/agent/id/branches';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"sourceBranchId":"5f8d0d55b54764421b7156c3","name":"feature/user-authentication"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.smallest.ai/atoms/v1/agent/id/branches"

	payload := strings.NewReader("{\n  \"sourceBranchId\": \"5f8d0d55b54764421b7156c3\",\n  \"name\": \"feature/user-authentication\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.smallest.ai/atoms/v1/agent/id/branches")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"sourceBranchId\": \"5f8d0d55b54764421b7156c3\",\n  \"name\": \"feature/user-authentication\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.smallest.ai/atoms/v1/agent/id/branches")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"sourceBranchId\": \"5f8d0d55b54764421b7156c3\",\n  \"name\": \"feature/user-authentication\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.smallest.ai/atoms/v1/agent/id/branches', [
  'body' => '{
  "sourceBranchId": "5f8d0d55b54764421b7156c3",
  "name": "feature/user-authentication"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.smallest.ai/atoms/v1/agent/id/branches");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"sourceBranchId\": \"5f8d0d55b54764421b7156c3\",\n  \"name\": \"feature/user-authentication\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "sourceBranchId": "5f8d0d55b54764421b7156c3",
  "name": "feature/user-authentication"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.smallest.ai/atoms/v1/agent/id/branches")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```