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

# Run a report over HTTP

> Submit report parameters through the Agent API and collect asynchronous query progress from your backend.

Submit a report to **`POST https://<NEURON_HOST>/Agent/Xmpp/InformationQuery`**, then collect its result messages with **`POST https://<NEURON_HOST>/Agent/Xmpp/PopMessages`**.
Execution uses `type: "set"` and the `executeNodeQuery` XML command. Completion arrives asynchronously.

Run this sequence in a backend job when serving a dashboard. Cache the completed result and reuse it across dashboard loads.
The [dashboard integration guide](/reports/dashboard-integration) covers scheduled jobs and controlled manual refreshes.

## Prepare the session and target

Complete [report discovery](/reports/quickstart) first. Your application needs a current JWT, the resolved full Reports JID,
an exact report ID, and its parameter form. The discovery sample logs out when it exits; obtain a new session for execution.

All requests below go to your provider's Agent API host. The full Reports JID belongs in `to`, even when it identifies another Neuron.
Keep the credentials and token on your backend. Replace the illustrative host, application URL, report ID, and parameter names with your values.
Use the same account and JWT for submission and polling.

## Fetch the current form

Send `POST https://neuron.example.com/Agent/Xmpp/InformationQuery`:

```http theme={null}
POST /Agent/Xmpp/InformationQuery HTTP/1.1
Host: neuron.example.com
Referer: https://your-app.example/
Authorization: Bearer <JWT>
Content-Type: application/json
Accept: application/json

{
  "to": "reports@neuron.example.com/current-resource",
  "type": "get",
  "xml": "<getCommandParameters xmlns='urn:nf:iot:concentrator:1.0' xml:lang='en' src='Reports' id='Client Reports\\Monthly usage.rpx' command='Execute'/>"
}
```

Check both the HTTP status and the response's `ok` property. On success, read the form from `Stanza.x`.
See [parameter forms](/reports/responses#parameter-forms) for the response structure.

## Submit the report

Generate a unique `queryId` for each execution and retain it to correlate result messages.
Submit an XMPP data form with `type='submit'`, using each field's exact `var` and `type`.
Include hidden fields returned by the form. Send one `<value>` element per value for a multi-value field.

Send `POST https://neuron.example.com/Agent/Xmpp/InformationQuery`, changing `type` to `set`:

```http theme={null}
POST /Agent/Xmpp/InformationQuery HTTP/1.1
Host: neuron.example.com
Referer: https://your-app.example/
Authorization: Bearer <JWT>
Content-Type: application/json
Accept: application/json

{
  "to": "reports@neuron.example.com/current-resource",
  "type": "set",
  "xml": "<executeNodeQuery xmlns='urn:nf:iot:concentrator:1.0' xml:lang='en' src='Reports' id='Client Reports\\Monthly usage.rpx' command='Execute' queryId='client-run-unique-id'><x xmlns='jabber:x:data' type='submit'><field var='Month' type='text-single'><value>2026-08</value></field></x></executeNodeQuery>"
}
```

Use an XML builder or escape XML text and attribute values before embedding them in the request. Use your language's JSON serializer for the outer body.
For a report with no fields, send an empty submit form: `<x xmlns='jabber:x:data' type='submit'/>`.

A successful response has `ok: true`, for example with other fields omitted:

```json theme={null}
{ "ok": true }
```

**This acknowledges the query; it does not contain the completed report.**
Check the HTTP status and `ok`; stop on a failed query and inspect its sanitized error fields.
Record the query ID and start collecting progress.

## Collect progress messages

For a backend using polling, send `POST https://neuron.example.com/Agent/Xmpp/PopMessages`:

```http theme={null}
POST /Agent/Xmpp/PopMessages HTTP/1.1
Host: neuron.example.com
Referer: https://your-app.example/
Authorization: Bearer <JWT>
Content-Type: application/json
Accept: application/json

{ "maxCount": 100 }
```

The response contains `Messages`. Each message contains its sender and a `Content` array of XML elements represented as JSON.
Find elements with `__name: "queryProgress"` and `__ns: "urn:nf:iot:concentrator:1.0"`.
Match the expected sender, `queryId`, source `Reports`, and report `id` before using the data.

Illustrative completion message, with unrelated fields omitted:

```json theme={null}
{
  "Messages": [
    {
      "from": "reports@neuron.example.com/current-resource",
      "Content": [
        {
          "__name": "queryProgress",
          "__ns": "urn:nf:iot:concentrator:1.0",
          "src": "Reports",
          "id": "Client Reports\\Monthly usage.rpx",
          "queryId": "client-run-unique-id",
          "seqNr": "8",
          "queryDone": {
            "__name": "queryDone",
            "__ns": "urn:nf:iot:concentrator:1.0"
          }
        }
      ]
    }
  ]
}
```

Poll at an application-defined interval until `queryDone` or `queryAborted`, with an overall deadline appropriate for your report.
`Messages: []` means no queued messages were returned on that poll; it does not mean the report is complete.

<Warning>
  Pop Messages consumes queued messages for the whole account. Use one consumer that dispatches all messages, or a dedicated report account.
  Do not run competing pollers or discard unrelated messages. Matching browser event handlers redirect messages to client events instead of this queue.
</Warning>

Preserve each batch before processing it. Track `seqNr` as a number, handle duplicate or out-of-order progress,
and do not silently label a report complete if earlier progress is missing.
If a poll response is lost after the server consumes its messages, this queue does not provide a replay acknowledgment protocol.

## Assemble the result

| Progress element             | Client action                                                                        |
| ---------------------------- | ------------------------------------------------------------------------------------ |
| `queryStarted`               | Mark execution as started.                                                           |
| `title`                      | Read the report title from `name`.                                                   |
| `beginSection`, `endSection` | Maintain the section hierarchy; `beginSection.header` is the heading.                |
| `newTable`                   | Create a table using `tableId`, `tableName`, and the `column` definitions.           |
| `newRecords`                 | Append `record` cells to the table identified by `tableId`, preserving column order. |
| `tableDone`                  | Mark that table complete. Other tables or objects can still follow.                  |
| `newObject`                  | Retain `contentType` and Base64 content from `value`.                                |
| `queryMessage`               | Retain the message's `level` and text in `value`.                                    |
| `status`                     | Update progress text from `message`.                                                 |
| `queryDone`                  | Mark the query complete after preceding progress has been processed.                 |
| `queryAborted`               | Mark the query aborted; any collected output is partial.                             |

Raw HTTP polling returns these messages. It does not automatically produce the JavaScript helper's `Tables`, `Sections`, and `Objects` object.
Use the [response guide](/reports/responses) to interpret cells or to design a comparable result model.

Set a client deadline and keep the query ID for diagnostics. A client timeout does not cancel the server query.
Avoid automatically resubmitting timed-out reports: they may still be running, and report scripts can perform work beyond reading data.

## End the session

After collecting the result, send `POST https://neuron.example.com/Agent/Account/Logout` and discard the JWT:

```http theme={null}
POST /Agent/Account/Logout HTTP/1.1
Host: neuron.example.com
Referer: https://your-app.example/
Authorization: Bearer <JWT>
Content-Type: application/json
Accept: application/json

{}
```
