> ## Documentation Index
> Fetch the complete documentation index at: https://docs.akapulu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Endpoints

> Create, configure, and attach endpoints for scenario tools.

Endpoints let your assistant call external services during a live conversation.

Use them when a scenario needs to trigger backend actions such as CRM updates, scheduling, order lookups, or workflow events.
This guide covers endpoint setup and attachment in both JSON and UI flows.

## What an endpoint includes

Each endpoint has:

* `name`: tool label shown in Akapulu Labs
* `url`: destination HTTP URL
* `headers`: request headers
* `body`: JSON payload

<Note>
  Akapulu Labs invokes your endpoint with the **POST** method and a JSON-encoded body. **`Content-Type: application/json`** is sent by default; add **`Content-Type`** under **Headers** if you need a different value.
</Note>

## Host your endpoint as an HTTP server

Your endpoint URL must point to a running HTTP server route that can accept POST requests from Akapulu Labs during live conversations.

* Use a valid `https://` URL for production.
* The route must be publicly reachable from the internet.

<Note>
  For authentication, create a [secret](https://akapulu.com/secrets) and pass it in your request **Headers** using `{{secret.*}}`.
</Note>

## HTTP transition behavior

HTTP endpoint tools support two transition patterns:

* **Simple transition**: set `transition_to` on the HTTP function. If the endpoint returns a successful **2xx** response, the flow transitions to that node.
* **Dynamic transition**: set `allowed_next_nodes` on the HTTP function. After a successful **2xx** response, Akapulu Labs reads the returned JSON field `next_node` and transitions to that node.

For dynamic transitions:

* the endpoint response must be a JSON object
* it must include `next_node`
* `next_node` must be a string
* `next_node` must match one of the nodes listed in `allowed_next_nodes`
* every entry in `allowed_next_nodes` must be a valid node name in the scenario

If an HTTP endpoint is unreachable or returns a non-2xx response such as `400` or `500`, the flow does **not** transition to any node.

If dynamic transition is configured and the response is missing `next_node`, returns a non-string `next_node`, or returns a `next_node` that is not in `allowed_next_nodes`, the tool call is treated as an error and the flow does **not** transition.

<Note>
  Tool call results are included in conversation transcripts. For failed HTTP tools, Akapulu Labs stores a sanitized error message rather than the raw upstream error text.
</Note>

## Create an endpoint

1. Go to [akapulu.com/endpoints](https://akapulu.com/endpoints) and click **Create Endpoint**.
2. In the **Setup** tab, enter:
   * endpoint `name`
   * destination `url`
   * example:
     * `name`: `Book Appointment`
     * `url`: `https://api.yourcompany.com/v1/book-appointment`
3. In the **Headers** tab, add a JSON object for request headers.
   * example:

```json theme={null}
{
  "Content-Type": "application/json",
  "Authorization": "Bearer {{secret.crm_token}}"
}
```

4. In **Body**, add a JSON object for the request payload.
   * example:

```json theme={null}
{
  "patient_id": "{{runtime.patient_id}}",
  "date": "{{llm.date:Appointment date in YYYY-MM-DD}}",
  "time": "{{llm.time:Appointment time in HH:MM}}"
}
```

* Note: You can use template variables in headers and body. Learn more in [Templates and Variables](/guides/endpoints/templates-and-variables).
* Note: Secret variables are allowed only in endpoint headers. Secret variables are not allowed in request bodies, `role_instruction`, or `task_instruction`.

5. Save the endpoint and copy its endpoint ID from the details view.
6. Attach the endpoint to your scenario using one of these methods:

### Attach via JSON

Use your endpoint ID in node JSON:

In `nodes_json`, endpoint references live inside each node object under:

* `functions[].endpoint_id` for HTTP tools

For HTTP tools, `functions[].name` is the tool-call name presented to the LLM. Use clear action names like `book_appointment`, `create_lead`, or `lookup_order`.

Example shape inside `nodes` json:

```json theme={null}
{
  "nodes": {
    "<node_name>": {
      "functions": [
        {
          "type": "http",
          "name": "function_name",
          "description": "Describe when the assistant should call this endpoint.",
          "endpoint_id": "<YOUR_ENDPOINT_ID>"
        }
      ],
      "task_instruction": "<TASK_INSTRUCTION_PLACEHOLDER>"
    }
  }
}
```

**Simple transition** example:

```jsonc theme={null}
{
  "name": "book_demo",
  "description": "Create a demo booking and move to the confirmation node.",
  "type": "http",
  "endpoint_id": "<YOUR_ENDPOINT_ID>",
  "transition_to": "Booking Confirmation"
  // On a successful 2xx response, the flow transitions to "Booking Confirmation".
}
```

**Dynamic transition** example:

```jsonc theme={null}
{

  "initial_node": "Route Request",

  "nodes": {

    // Starting node
    "Route Request": {

      "task_instruction": "Figure out what kind of help the user needs, then call the routing endpoint.",
      "functions": [
        {
          "name": "route_demo_request",
          "description": "Choose which node should handle the request next.",
          "type": "http",
          "endpoint_id": "<YOUR_ENDPOINT_ID>",
      
          // Akapulu Labs will only transition to one of these connected node names.
          "allowed_next_nodes": ["Pricing Help", "Technical Help", "General Overview"]
        
          // The endpoint must return JSON with "next_node" set to
          // "Pricing Help", "Technical Help", or "General Overview".
          // If "next_node" is missing, not a string, or not in allowed_next_nodes,
          // the tool call is treated as an error and the flow does not transition.
        }
      ]
    },

    // One allowed dynamic destination.
    "Pricing Help": {
      "task_instruction": "Answer questions about plans, pricing, and billing."
    },

    // Another allowed dynamic destination.
    "Technical Help": {
      "task_instruction": "Answer questions about integrations, APIs, and implementation details."
    },

    // Another allowed dynamic destination.
    "General Overview": {
      "task_instruction": "Give a broad overview of the product and help the user decide what to explore next."
    }
  }
}
```

Example response handler:

```python theme={null}
# Example: https://my-endpoint.com

from fastapi import FastAPI

app = FastAPI()

@app.post("/route-demo-request")
def route_demo_request():
    return {
        "status": "success",
        "message": "Send this user to pricing.",
        "next_node": "Pricing Help", # Akapulu Labs will read next_node to transition
    }
```

When creating HTTP Endpoint:

* set the endpoint `url` to the deployed route for your handler`https://my-endpoint.com/route-demo-request`
* Akapulu Labs will call your endpoint and return the result to the conversation flow
* JSON response will be added to llm context and will transition to the "Pricing Help" node

### Attach via UI

#### HTTP function tool (LLM-invoked)

Use this when you want the model to decide when to call the endpoint during a node:

1. Open your scenario and go to the node where you want to add the tool.
2. Click **Add Function**.
3. Select the **HTTP Endpoints** tab in the modal.
4. Choose your endpoint by name.
5. Enter a clear function name and description. This is the tool metadata shown to the model when it decides whether to call the endpoint.
6. Use the transition toggle at the bottom of the modal to choose **Simple** or **Dynamic** transition behavior.
7. Configure the transition path for the endpoint:
   * For **Simple**, drag the function probe to the single next node you want to enter after a successful tool result.
   * For **Dynamic**, drag the function probe to each node you want to allow. Each connected node is added to `allowed_next_nodes`.
     <Note>
       For dynamic routing, the endpoint must return JSON with `next_node` set to one of the node names in `allowed_next_nodes`.
     </Note>

This attaches an HTTP endpoint as a **function tool** the LLM can call within that node.

Endpoints can be reused across multiple scenarios.

## Next step

After creating an endpoint, configure variables in headers/body using the [Templates and Variables](/guides/endpoints/templates-and-variables) guide.
