> For the complete documentation index, see [llms.txt](https://docs.nexthink.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexthink.com/configuring_nexthink/bringing-data-into-your-nexthink-instance/integrating-nexthink-with-third-party-tools/integrating-spark-with-existing-agents/spark-agent2agent-integration.md).

# Connecting Spark to your AI agent through Agent2Agent

{% hint style="warning" %}
This documentation references external sources. Nexthink does not have control over the accuracy of third-party documentation, nor any external updates or changes that might create inconsistencies with the information presented on this page. Please report any errors or inconsistencies to [Nexthink Support](https://support.nexthink.com/).
{% endhint %}

Connect Spark to your existing enterprise AI bots using the [Agent-to-Agent (A2A)](https://a2a-protocol.org/latest/) protocol. Employees keep working in the chat tools they already use, and Spark answers with device and user insights from Nexthink.

A2A is an open standard that enables seamless communication and collaboration between AI agents. Through A2A, third-party agents can:

* Discover Spark capabilities through the Spark agent card.
* Send employee requests to Spark.
* Receive asynchronous answers from Spark.
* Present the answers to the employee in readable form.

As a result, employees experience no disruption to existing workflows while seamlessly extending them with Spark’s intelligence and Nexthink context.

This page describes how to set up agent-to-agent communication with the public, vendor-neutral [Spark A2A API](/api/spark/agent-to-agent.md).

{% hint style="info" %}
If your organization does not use A2A-compatible AI agents, you can still give employees access to Spark through existing chat entry points by implementing a lightweight chatbot integration directly with the Spark API.

Refer to [Spark Handoff API](https://docs.nexthink.com/api/spark/handoff-api) for more information.
{% endhint %}

## Key benefits

* Integrate external AI agents with **Spark API** using a standardized protocol.
* Extend existing chatbot and orchestration workflows with Nexthink capabilities.
* Enable multi-turn conversations using context-aware interactions.
* Maintain user context across conversations using metadata and task tracking.
* Ensure enterprise security with authenticated, service-to-service communication.

## Understanding architecture and authentication

A2A splits the two sides of a conversation into roles:

* **A2A Server (remote agent):** the agent that does the work. In this integration, that’s Spark.
* **A2A Client:** the agent that sends requests on the employee’s behalf. This is your AI agent or orchestrator. It is the only side that calls Spark.

Two separate trust relationships apply, one for each direction.

| Direction               | Mechanism                                                                                                                                                                                     | Configured in                                                             |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Client agent to Spark   | OAuth 2.0 client credentials. The client exchanges its client ID and secret for an access token, then sends the token as a bearer token with every request, including the agent card request. | **Administration > API Credentials**, with the **Spark API** permission   |
| Spark to client webhook | Spark calls the webhook through Nexthink, using the authorization defined in the matching third-party credentials, such as basic authentication or a bearer token.                            | **Administration > Third-party credentials**, with the **HTTPS** protocol |

Communication is asynchronous. The AI agent doesn’t talk to Spark directly for answers. It sends a message, receives an acknowledgment right away, and gets the real answer later at a webhook it exposes. Because of that, the client needs two things:&#x20;

* **Third-party credentials**: A way to authenticate to Spark. Refer to [#create-third-party-credentials-for-the-webhook](#create-third-party-credentials-for-the-webhook "mention").
* **A webhook**: A public HTTPS endpoint that you expose, and Spark calls it to deliver answers and status updates. Refer to [#handle-webhook-deliveries](#handle-webhook-deliveries "mention").&#x20;

{% hint style="warning" %}
Spark delivers answers only to webhook URLs registered as third-party credentials. A message whose webhook URL does not exactly match a registered URL is rejected when you send it. Spark never pushes an answer to an unregistered endpoint.
{% endhint %}

Spark publishes an **Agent Card**, which is a JSON document that describes Spark, its interface URLs, and its capabilities. The A2A client reads the Agent Card to discover Spark and to find out which capabilities it supports. Refer to [#user-content-protocol-and-capabilities](#user-content-protocol-and-capabilities "mention") for more information.

Spark does not take the **employee identity** from the access token. It takes the identity from the `userPrincipalName` field in the message metadata, which contains the employee's email address. Your AI agent must send the identity of the employee it authenticated. Spark uses it to act on behalf of that employee.

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2FXZuyn7m09PiySFmJNs7M%2FSPARK-hbjgd14yug564vadxh7bKKh.webp?alt=media&amp;token=957cc729-810c-4b93-9ec1-895e84caef8f" alt=""><figcaption></figcaption></figure>

## Understanding Spark A2A workflow

This section describes the end-to-end flow, from the moment an employee asks a question to the moment they receive an answer.&#x20;

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2FUwLaEQIyKAtAhht5lOCF%2FSpark_a2a_workflow_202604281552.png?alt=media&amp;token=08d32e20-7be4-42d1-8b92-ea922a45f102" alt=""><figcaption></figcaption></figure>

Once you complete the setup in [Configuring Agent2Agent integration](https://claude.ai/epitaxy/local_4049abf5-cdf1-4e7f-a7ad-a7b5c3cce719#configuring-agent2agent-integration), the workflow runs as follows:

1. The employee reports an issue, requests a service, or asks a question in the existing chatbot (your AI agent).
2. Your AI agent reads Spark's agent card and identifies Spark as the right subagent.
3. Your AI agent sends the request to the `message:send` endpoint. The request includes the bearer token, a unique `messageId`, `userPrincipalName` in the metadata, and the webhook URL in `configuration.taskPushNotificationConfig.url`. Follow-up messages also include the `contextId` and `taskId` values.&#x20;

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>Step 3 uses the client-to-Spark trust relationship, through the bearer token.</p></div>
4. Spark checks the webhook URL against the registered [third-party credentials.](#create-third-party-credentials-for-the-webhook) If the URL does not match exactly, Spark rejects the message.
5. Spark returns an **acknowledgment**. The aknowledgment is not the answer, it is the immediate reply that Spark sends when it accepts a message to confirms the message was received. In the aknowledgment Spark returns `contextId`, `taskId`, and the state `TASK_STATE_WORKING`. Your AI agent stores both values. Refer to [#user-content-track-a-conversation](#user-content-track-a-conversation "mention") for more information.
6. Spark processes the request. If the request includes the `A2A-Extensions` header, Spark can send tool updates to the webhook while it works. Refer to [#user-content-display-tool-updates](#user-content-display-tool-updates "mention") for more information.
7. Spark sends the answer, or a status update, to the webhook. It uses the authorization defined in the [registered third-party credentials](#create-third-party-credentials-for-the-webhook).

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p> Step 7 uses the Spark-to-webhook trust relationship.</p></div>
8. The webhook returns a `2xx` status quickly and processes the payload asynchronously. It uses the `messageId` to discard duplicate deliveries.
9. Your AI agent shows the answer to the employee, based on the task state. It shows tool updates as temporary status.
10. For the next employee message, your AI agent sends the same `contextId` and `taskId`, then returns to step 3.

### Track a conversation <a href="#user-content-track-a-conversation" id="user-content-track-a-conversation"></a>

Spark acknowledges each message immediately. The **acknowledgment** is the reply that confirms Spark accepted the message. It is not the answer. The answer follows later, as a separate delivery to your webhook.

Spark generates two values on the first message and returns them in the acknowledgment:

* `contextId` identifies the conversation. Every message in the same back-and-forth shares it.
* `taskId` identifies the task that tracks the current request within the conversation.

Your AI agent stores both values from the acknowledgment and sends them with every follow-up message. Spark uses them to link each follow-up to the same conversation. A message without these values starts a new conversation, so the context is lost without an error.

Each message also carries a `messageId`, which is a unique identifier that your AI agent generates. Spark uses it to tell messages apart. Your webhook uses it to detect duplicate deliveries.

Each response includes a **task state.** Spark uses the state to decide what your AI agent shows the employee:

| Task state                  | Meaning                                                                                                                 | What the AI agent shows                                                                               |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `TASK_STATE_WORKING`        | Spark accepted the message and is processing it. This state also appears in the acknowledgment and in progress updates. | A waiting indicator. Replace it with the answer when it arrives.                                      |
| `TASK_STATE_COMPLETED`      | Spark answered.                                                                                                         | The answer. The employee can send another message in the same conversation.                           |
| `TASK_STATE_INPUT_REQUIRED` | Spark needs more information from the employee.                                                                         | Spark's question. Wait for the employee's reply, then send it with the same `contextId` and `taskId`. |
| `TASK_STATE_FAILED`         | Spark could not process the message.                                                                                    | A message that the request failed, and an option to retry.                                            |

Spark delivers status updates for a conversation in the order it produces them.

### Protocol and capabilities <a href="#user-content-protocol-and-capabilities" id="user-content-protocol-and-capabilities"></a>

Nexthink Spark API supports the following capabilities:

* **Protocol:** [Agent2Agent (A2A)](https://a2a-protocol.org/), version 1.0.
* **Bindings:** Bindings are the ways to send A2A requests. Spark supports HTTP+JSON (REST) and JSON-RPC 2.0, with the same behavior. gRPC is not supported. Choose the binding that your agent framework uses.
* **Agent Card:** You can find the Spark Agent Card at the following URL `https://<your-instance>.api.<your-region>.nexthink.cloud/api/spark/a2a/.well-known/agent-card.json`. Replace `<your-instance>` and `<your-region>` with your tenant values. The Agent Card lists the interface URLs for your instance and requires authentication.

The following table lists the A2A capabilities that the Spark API supports.

| Capability                                                                                                                         | Support                                                                                                                                           |
| ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Agent card](https://a2a-protocol.org/latest/specification/#8-agent-discovery-the-agent-card)                                      | Supported                                                                                                                                         |
| [Send message](https://a2a-protocol.org/latest/specification/#311-send-message) (`message:send` / `SendMessage`)                   | Supported                                                                                                                                         |
| Push notifications                                                                                                                 | Supported. Spark sends answers to a webhook that you set on each message. There is no separate push notification configuration.                   |
| Tool updates extension                                                                                                             | Supported. Optional. See [Display tool updates](https://claude.ai/epitaxy/local_4049abf5-cdf1-4e7f-a7ad-a7b5c3cce719#display-tool-updates).       |
| [Streaming](https://a2a-protocol.org/latest/specification/#312-send-streaming-message) (`SendStreamingMessage`, `SubscribeToTask`) | Not supported. Spark delivers answers only through push notifications.                                                                            |
| [Task management](https://a2a-protocol.org/latest/specification/#313-get-task) (`GetTask`, `ListTasks`, `CancelTask`)              | Not supported. These operations let the AI agent query or cancel tasks directly. Track task state from the responses and webhook updates instead. |
| [Push notification configuration operations](https://a2a-protocol.org/latest/specification/#317-create-push-notification-config)   | Not supported. These operations register a webhook separately from a message. Spark takes the webhook URL on each message.                        |
| [Extended agent card](https://a2a-protocol.org/latest/specification/#3111-get-extended-agent-card)                                 | Not supported                                                                                                                                     |
| Input content format                                                                                                               | Text and image                                                                                                                                    |
| Output content format                                                                                                              | Text only                                                                                                                                         |

### Display tool updates <a href="#user-content-display-tool-updates" id="user-content-display-tool-updates"></a>

While Spark works on a request, it can report intermediate progress, such as "Running device diagnostics".&#x20;

To enable this capability, you need to pass the URI extension `https://docs.nexthink.com/spark/a2a/tool-updates/v1`  in the `A2A-Extensions` header. Without the extension, the employee waits silently until the answer arrives. With it, the employee sees progress during longer requests.

Some things to consider:&#x20;

* If you omit the `A2A-Extensions`  header, the AI agent receives only the answer.
* Check activation in the `A2A-Extensions` header of the acknowledgment. If the header is absent, the extension is not active for that message.
* Recognize tool updates on the webhook. They are status updates in the `TASK_STATE_WORKING` state, and their message lists the extension URI in `extensions`.
* Show tool updates as a transient status, such as a typing indicator. Replace them with the answer when it arrives. Tool updates are not answers.

To learn more about A2A extensions, refer to the [official A2A extensions documentation](https://a2a-protocol.org/latest/topics/extensions/).

### Payload requirements <a href="#user-content-payload-requirements" id="user-content-payload-requirements"></a>

The [Spark A2A API](/api/spark/agent-to-agent.md) documents every field. These rules matter most when you integrate:

* **Employee identity:** include `userPrincipalName` (the employee's email address) in `message.metadata` on every message.
* **Message identifier:** generate a unique `messageId` for each message.
* **Conversation identifiers:** omit `contextId` and `taskId` on the first message. On follow-up messages, reuse the values that Spark returns.
* **Webhook URL:** include `configuration.taskPushNotificationConfig.url` on every message. The URL must exactly match the URL of the third-party credentials.
* **Content:** send text parts in messages.

The following example shows the first message in a conversation:

{% code overflow="wrap" %}

```json
{
  "message": {
    "messageId": "{unique message ID}",
    "role": "ROLE_USER",
    "parts": [
      {
        "text": "{employee request}"
      }
    ],
    "metadata": {
      "userPrincipalName": "{employee email address}"
    }
  },
  "configuration": {
    "taskPushNotificationConfig": {
      "url": "https://{host}[:{port}][/{path}]"
    }
  }
}
```

{% endcode %}

For a follow-up message, add the `contextId` and `taskId` values that Spark returned in the acknowledgment. Use a new `messageId`.

```json
{
  "message": {
    "messageId": "{unique message ID}",
    "contextId": "{contextId from the acknowledgment}",
    "taskId": "{taskId from the acknowledgment}",
    "role": "ROLE_USER",
    "parts": [
      {
        "text": "{follow-up message}"
      }
    ],
    "metadata": {
      "userPrincipalName": "{employee email address}"
    }
  },
  "configuration": {
    "taskPushNotificationConfig": {
      "url": "https://{host}[:{port}][/{path}]"
    }
  }
}
```

In both examples, replace `{host}` and `{port}` and the path with your registered webhook URL. The `role` field identifies the message sender as the user.

## Configuring Agent2Agent integration

### Prerequisites

Ensure the following prerequisites are met to integrate your existing AI bot with Spark using A2A protocol:

* Spark is configured and integrated in your environment. For more information, see the [Setting up and managing Spark](/user-guide/spark/setting-up-and-managing-spark.md) documentation.
* You need to have the **Administrator** role in Nexthink Infinity. For more information, see the [Roles](/user-guide/administration/account-management/roles.md) documentation.

Complete the following steps to integrate your AI agent with Spark through A2A.

{% stepper %}
{% step %}

### Create Spark API credentials

Create OAuth client credentials that your agent uses to send authenticated requests to Spark. In the Nexthink web interface:

1. Go to **Administration > API Credentials,** select the **New OAuth client credentials** button.
2. Provide a name and optional description. Select the **Spark API** permission.
3. Select **Save and generate credentials**.
4. After saving your credentials, a new modal appears with the OAuth client credentials. Copy the **client ID** and **secret key**. They're shown only once.

{% hint style="success" icon="pencil" %}
At the end of this step, make sure you have recorded the following information for use in the next steps:

* **Client ID** and **secret key**
  {% endhint %}
  {% endstep %}

{% step %}

### Create third-party credentials for the webhook

Register your webhook endpoint so that Spark can send asynchronous answers to it. In the Nexthink web interface:

1. From the **Administration > Third-party credentials,** select the **New credentials** button.
2. Provide a unique credentials name and select **Hypertext Transfer Protocol Secure (HTTPS)** from the **Protoco**l drop-down menu.
3. Enter the exact URL that your external agent exposes. Use the format `https://{host}[:{port}][/{path}]`. Use the same URL in the `configuration.taskPushNotificationConfig.url` field of your messages.
4. Select the authorization method that your webhook expects.
   {% endstep %}

{% step %}

### Connect your agent with the A2A client SDK

Configure your external agent using the A2A client SDK to communicate with the Spark A2A API.

1. Set the SDK base URL to `https://[instance].api.[region].nexthink.cloud/api/spark/a2a/v1`, or configure the SDK with the agent card URL.
2. Authenticate every request using the Client ID and secret key from the OAuth client credentials.
3. Send messages through the SDK using the `message:send` endpoint.
4. Include the user identity in each request by setting the `userPrincipalName` (email address) in the `metadata` field of the payload.
5. Ensure each request:
   * Contains unique `messageId` (generated by the client)
   * For follow-up messages, reuses the `contextId` and `taskId` that Spark returned. If you omit them, Spark starts a new conversation.
6. Configure a webhook URL to receive asynchronous push notifications from Spark. Set `configuration.taskPushNotificationConfig.url` to the&#x20;

   URL in your message payload to match the one registered in [#create-third-party-credentials-for-the-webhook](#create-third-party-credentials-for-the-webhook "mention").
7. Store the `contextId` and `taskId` from the first response. Read the task state in each response to decide what to show the employee.

Refer to the [official Agent2Agent documentation](https://a2a-protocol.org/latest/specification/#321-sendmessagerequest) for more information.
{% endstep %}

{% step %}

### Handle webhook deliveries

Process the answers that Spark sends to your webhook.

* Return a `2xx` status code quickly. Process the payload asynchronously.
* Use the `messageId` of each status update to discard duplicate deliveries that come from retries.
* Show tool updates as transient status only, and replace them with the answer when it arrives. Refer to [#user-content-display-tool-updates](#user-content-display-tool-updates "mention").
  {% endstep %}
  {% endstepper %}

{% hint style="info" %}
Spark supports only the `agent card` and `message:send` operations for A2A clients. Streaming, task management, and push notification configuration operations are not supported.&#x20;
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.nexthink.com/configuring_nexthink/bringing-data-into-your-nexthink-instance/integrating-nexthink-with-third-party-tools/integrating-spark-with-existing-agents/spark-agent2agent-integration.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
