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

# Start Agent

Send a message to a Gumloop agent and start an asynchronous interaction. Returns immediately with an `interaction_id` that you use to [poll for results](/api-reference/running-an-agent/retrieve-agent-status).

To **continue an existing conversation**, pass the `interaction_id` from a previous run. The new message is appended to that conversation's history and the same `interaction_id` is reused. See [Continuing a Conversation](#continuing-a-conversation) below.

## Request

### Headers

```text theme={"dark"}
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
```

### Body Parameters

<ParamField body="gummie_id" type="string" required>
  The unique identifier of the agent to trigger. See [Finding Your Agent ID](#finding-your-agent-id) below.
</ParamField>

<ParamField body="message" type="string" required>
  The message/prompt to send to the agent. This is a natural language string, not structured inputs.
</ParamField>

<ParamField body="user_id" type="string">
  Your Gumloop user ID. Required if `project_id` is not provided.
</ParamField>

<ParamField body="project_id" type="string">
  Your team (workspace) ID. Required if `user_id` is not provided. Can be combined with `user_id`.
</ParamField>

<ParamField body="interaction_id" type="string">
  The `interaction_id` from a previous completed or failed interaction. When provided, the new message is appended to the existing conversation and the same `interaction_id` is reused. The previous interaction must be in a terminal state (`COMPLETED` or `FAILED`).
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl -X POST https://api.gumloop.com/api/v1/start_agent \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -d '{
      "gummie_id": "abc123DEFghiJKL",
      "message": "Summarize the latest sales report and send it to the team Slack channel",
      "user_id": "your_user_id",
      "project_id": "your_project_id"
    }'
  ```

  ```python Python theme={"dark"}
  import requests

  url = "https://api.gumloop.com/api/v1/start_agent"
  headers = {
      "Content-Type": "application/json",
      "Authorization": "Bearer YOUR_API_KEY"
  }
  data = {
      "gummie_id": "abc123DEFghiJKL",
      "message": "Summarize the latest sales report and send it to the team Slack channel",
      "user_id": "your_user_id",
      "project_id": "your_project_id"
  }

  response = requests.post(url, headers=headers, json=data)
  print(response.json())
  ```

  ```javascript JavaScript theme={"dark"}
  const url = "https://api.gumloop.com/api/v1/start_agent";
  const headers = {
    "Content-Type": "application/json",
    Authorization: "Bearer YOUR_API_KEY",
  };
  const data = {
    gummie_id: "abc123DEFghiJKL",
    message: "Summarize the latest sales report and send it to the team Slack channel",
    user_id: "your_user_id",
    project_id: "your_project_id",
  };

  fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(data),
  })
    .then((response) => response.json())
    .then((data) => console.log(data));
  ```
</CodeGroup>

## Response

### Success (202 Accepted)

<ResponseField name="interaction_id" type="string">
  Unique identifier for this interaction. Use this to poll for results via the [Retrieve Agent Status](/api-reference/running-an-agent/retrieve-agent-status) endpoint.
</ResponseField>

<ResponseField name="status" type="string">
  Always `"processing"` on success, indicating the agent has started working.
</ResponseField>

```json theme={"dark"}
{
  "interaction_id": "xYz789AbCdEfGhI",
  "status": "processing"
}
```

### Error Responses

| Status Code | Error                                                                             | Description                                                                                                                         |
| ----------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| 400         | `"gummie_id is required"`                                                         | Missing `gummie_id` in the request body.                                                                                            |
| 400         | `"message is required"`                                                           | Missing `message` in the request body.                                                                                              |
| 400         | `"project_id or user_id is required"`                                             | Missing both `project_id` and `user_id`.                                                                                            |
| 401         | `"Authorization header with Bearer token or api_key query parameter is required"` | No API key provided.                                                                                                                |
| 403         | `"Unauthorized"`                                                                  | Invalid API key.                                                                                                                    |
| 403         | `"unauthorized_gummie_access"`                                                    | User doesn't have permission to access this agent.                                                                                  |
| 403         | `"unauthorized_interaction_access"`                                               | User doesn't have permission to access the specified interaction (continuation only).                                               |
| 404         | `"gummie_not_found"`                                                              | No agent found with the provided `gummie_id`.                                                                                       |
| 404         | `"interaction_not_found"`                                                         | No interaction found with the provided `interaction_id` (continuation only).                                                        |
| 400         | `"interaction_gummie_mismatch"`                                                   | The `interaction_id` belongs to a different agent than the specified `gummie_id` (continuation only).                               |
| 409         | `"interaction_not_in_terminal_state"`                                             | The interaction is still processing and cannot be continued yet. Wait until it reaches `COMPLETED` or `FAILED` (continuation only). |

***

## Finding Your Agent ID

The `gummie_id` is the unique identifier for your Gumloop agent. You can find it from the URL when viewing your agent:

```text theme={"dark"}
https://www.gumloop.com/agents/{gummie_id}
```

For example, if your URL is `https://www.gumloop.com/agents/abc123DEFghiJKL`, then your `gummie_id` is `abc123DEFghiJKL`.

You can also find the agent ID on the agent's settings/configuration page in the Gumloop app.

***

## Complete Workflow

After starting an agent interaction, poll for results:

```text theme={"dark"}
1. POST /api/v1/start_agent
   → Send: gummie_id, message, user_id (+ optional project_id)
   → Receive: interaction_id, status: "processing"

2. GET /api/v1/agent_status/{interaction_id}  (poll repeatedly)
   → While state == "ASYNC_PROCESSING": wait and poll again
   → When state == "COMPLETED": read response and/or messages
   → When state == "FAILED": read error_message
```

<Tip>See the [Retrieve Agent Status](/api-reference/running-an-agent/retrieve-agent-status) endpoint for full details on polling and response schemas.</Tip>

***

## Continuing a Conversation

To continue an existing conversation, include the `interaction_id` from a previous run in your request body. The agent receives the full prior message history plus your new message, so it can respond with awareness of the earlier context.

### Requirements

* The previous interaction must be in a **terminal state** (`COMPLETED` or `FAILED`)
* The `gummie_id` must match the agent that owns the interaction
* The caller must have access to the interaction

### Continuation Flow

```text theme={"dark"}
1. POST /api/v1/start_agent  (initial request)
   → Send: gummie_id, message, user_id
   → Receive: interaction_id, status: "processing"

2. GET /api/v1/agent_status/{interaction_id}  (poll until COMPLETED)

3. POST /api/v1/start_agent  (follow-up request)
   → Send: gummie_id, message, user_id, interaction_id (from step 1)
   → Receive: same interaction_id, status: "processing"

4. GET /api/v1/agent_status/{interaction_id}  (poll until COMPLETED)
   → Messages now include the full conversation thread
```

### Example: Multi-Turn Conversation

<CodeGroup>
  ```python Python theme={"dark"}
  import requests
  import time

  API_KEY = "your_api_key"
  BASE_URL = "https://api.gumloop.com/api/v1"
  HEADERS = {
      "Content-Type": "application/json",
      "Authorization": f"Bearer {API_KEY}"
  }

  def send_message(gummie_id: str, message: str, user_id: str, interaction_id: str = None) -> dict:
      """Send a message to an agent, optionally continuing an existing conversation."""
      payload = {
          "gummie_id": gummie_id,
          "message": message,
          "user_id": user_id,
      }
      if interaction_id:
          payload["interaction_id"] = interaction_id

      response = requests.post(f"{BASE_URL}/start_agent", headers=HEADERS, json=payload)
      response.raise_for_status()
      return response.json()

  def wait_for_completion(interaction_id: str, user_id: str) -> dict:
      """Poll until the interaction completes or fails."""
      while True:
          response = requests.get(
              f"{BASE_URL}/agent_status/{interaction_id}",
              headers=HEADERS,
              params={"user_id": user_id}
          )
          response.raise_for_status()
          result = response.json()

          if result["state"] == "COMPLETED":
              return result
          elif result["state"] == "FAILED":
              raise RuntimeError(f"Agent failed: {result.get('error_message')}")
          time.sleep(2)

  # Turn 1: Start a new conversation
  start = send_message(
      gummie_id="abc123DEFghiJKL",
      message="Find all open support tickets from Acme Corp",
      user_id="your_user_id"
  )
  interaction_id = start["interaction_id"]
  result = wait_for_completion(interaction_id, "your_user_id")
  print(f"Turn 1: {result['response']}")

  # Turn 2: Continue the conversation
  send_message(
      gummie_id="abc123DEFghiJKL",
      message="Now draft a summary email to send to the account manager",
      user_id="your_user_id",
      interaction_id=interaction_id  # reuse the same interaction
  )
  result = wait_for_completion(interaction_id, "your_user_id")
  print(f"Turn 2: {result['response']}")
  ```

  ```javascript JavaScript theme={"dark"}
  const API_KEY = "your_api_key";
  const BASE_URL = "https://api.gumloop.com/api/v1";

  async function sendMessage(gummieId, message, userId, interactionId = null) {
    const payload = { gummie_id: gummieId, message, user_id: userId };
    if (interactionId) payload.interaction_id = interactionId;

    const response = await fetch(`${BASE_URL}/start_agent`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${API_KEY}`,
      },
      body: JSON.stringify(payload),
    });
    if (!response.ok) throw new Error(await response.text());
    return response.json();
  }

  async function waitForCompletion(interactionId, userId) {
    while (true) {
      const response = await fetch(
        `${BASE_URL}/agent_status/${interactionId}?user_id=${userId}`,
        { headers: { Authorization: `Bearer ${API_KEY}` } }
      );
      const result = await response.json();

      if (result.state === "COMPLETED") return result;
      if (result.state === "FAILED")
        throw new Error(result.error_message || "Agent failed");
      await new Promise((r) => setTimeout(r, 2000));
    }
  }

  // Turn 1: Start a new conversation
  const start = await sendMessage(
    "abc123DEFghiJKL",
    "Find all open support tickets from Acme Corp",
    "your_user_id"
  );
  const interactionId = start.interaction_id;
  let result = await waitForCompletion(interactionId, "your_user_id");
  console.log("Turn 1:", result.response);

  // Turn 2: Continue the conversation
  await sendMessage(
    "abc123DEFghiJKL",
    "Now draft a summary email to send to the account manager",
    "your_user_id",
    interactionId // reuse the same interaction
  );
  result = await waitForCompletion(interactionId, "your_user_id");
  console.log("Turn 2:", result.response);
  ```
</CodeGroup>

***

## Full Example: Start and Poll

<CodeGroup>
  ```python Python theme={"dark"}
  import requests
  import time

  API_KEY = "your_api_key"
  BASE_URL = "https://api.gumloop.com/api/v1"
  HEADERS = {
      "Content-Type": "application/json",
      "Authorization": f"Bearer {API_KEY}"
  }

  def trigger_agent(gummie_id: str, message: str, user_id: str, project_id: str = None) -> dict:
      """
      Trigger a Gumloop agent and wait for the response.

      Args:
          gummie_id: The agent's unique ID
          message: The message to send to the agent
          user_id: Your Gumloop user ID
          project_id: Optional team/workspace ID

      Returns:
          dict with 'response' (agent's text reply) and 'messages' (full conversation)
      """
      # Step 1: Start the agent interaction
      payload = {
          "gummie_id": gummie_id,
          "message": message,
          "user_id": user_id,
      }
      if project_id:
          payload["project_id"] = project_id

      start_response = requests.post(
          f"{BASE_URL}/start_agent",
          headers=HEADERS,
          json=payload
      )
      start_response.raise_for_status()
      interaction_id = start_response.json()["interaction_id"]
      print(f"Started agent interaction: {interaction_id}")

      # Step 2: Poll for completion
      params = {"user_id": user_id}
      if project_id:
          params["project_id"] = project_id

      while True:
          status_response = requests.get(
              f"{BASE_URL}/agent_status/{interaction_id}",
              headers=HEADERS,
              params=params
          )
          status_response.raise_for_status()
          result = status_response.json()

          state = result["state"]
          if state == "COMPLETED":
              print(f"Agent response: {result['response']}")
              return result
          elif state == "FAILED":
              error_msg = result.get("error_message", "Unknown error")
              raise RuntimeError(f"Agent interaction failed: {error_msg}")
          else:
              # Still processing -- wait and poll again
              time.sleep(2)


  # Usage
  result = trigger_agent(
      gummie_id="abc123DEFghiJKL",
      message="Summarize the Q4 sales report",
      user_id="your_user_id",
      project_id="your_project_id"  # optional
  )

  print(result["response"])      # The agent's final text response
  print(result["messages"])       # Full conversation with tool call details
  ```

  ```javascript JavaScript theme={"dark"}
  const API_KEY = "your_api_key";
  const BASE_URL = "https://api.gumloop.com/api/v1";

  async function triggerAgent(gummieId, message, userId, projectId = null) {
    // Step 1: Start the agent interaction
    const payload = {
      gummie_id: gummieId,
      message: message,
      user_id: userId,
    };
    if (projectId) payload.project_id = projectId;

    const startResponse = await fetch(`${BASE_URL}/start_agent`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${API_KEY}`,
      },
      body: JSON.stringify(payload),
    });

    if (!startResponse.ok) {
      const error = await startResponse.json();
      throw new Error(`Failed to start agent: ${JSON.stringify(error)}`);
    }

    const { interaction_id } = await startResponse.json();
    console.log(`Started agent interaction: ${interaction_id}`);

    // Step 2: Poll for completion
    const params = new URLSearchParams({ user_id: userId });
    if (projectId) params.set("project_id", projectId);

    while (true) {
      const statusResponse = await fetch(
        `${BASE_URL}/agent_status/${interaction_id}?${params}`,
        {
          headers: { Authorization: `Bearer ${API_KEY}` },
        }
      );

      if (!statusResponse.ok) {
        const error = await statusResponse.json();
        throw new Error(`Failed to get status: ${JSON.stringify(error)}`);
      }

      const result = await statusResponse.json();

      if (result.state === "COMPLETED") {
        console.log(`Agent response: ${result.response}`);
        return result;
      } else if (result.state === "FAILED") {
        throw new Error(
          `Agent interaction failed: ${result.error_message || "Unknown error"}`
        );
      }

      // Still processing -- wait 2 seconds
      await new Promise((resolve) => setTimeout(resolve, 2000));
    }
  }

  // Usage
  triggerAgent(
    "abc123DEFghiJKL",
    "What were our top 3 deals this quarter?",
    "your_user_id",
    "your_project_id" // optional
  ).then((result) => {
    console.log(result.response);
    console.log(result.messages);
  });
  ```
</CodeGroup>

***

## Authentication Notes

* You can use either a **Personal API Key** or a **Team API Key**. See [Authentication](/api-reference/authentication) for details.
* If you authenticate with a personal API key and pass both `user_id` and `project_id`, the system verifies you are a member of the specified team before allowing the request.
* The agent uses the credentials associated with the `user_id` and `project_id` provided in the request.

<Info>The Python and JavaScript SDKs do not yet support agent triggering. Use the raw HTTP examples above until SDK support is added.</Info>
