> This page is for Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.emnify.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.emnify.com/_mcp/server.

# List Flow Log details

GET https://cdn.emnify.net/api/v1/endpoint/{endpointId}/flowlogs/detail

Required permissions Beta [Learn more](/developers/api-guidelines/permissions#how-permissions-work)`Endpoint.FlowLogs.Detail` + `List`Roles: AdministratorReturns individual (non-aggregated) Flow Log rows for a device, with pagination, filtering, and sorting.
Each row includes information such as `destination_ip`, `destination_port`, `protocol`, `bytes_up`, and `bytes_down`, and, when available, the `destination_hostname`, `pdp_context`, country, and network.By default, the response covers the last hour.
Use `started_from` in the `q` parameter to look back up to **30 days**.Filters follow the standard `q=<field>:<criteria>` syntax:- Combine multiple filters on different fields with `,` (AND).
- Combine multiple values for the same field with `||` (OR).Use `sort` to order the results and `page` / `per_page` to paginate.

Reference: https://docs.emnify.com/developers/api/flow-logs/list-endpoint-flow-logs-detail

## Authentication

- `Authorization` header (bearer token, required) — An `auth_token` should be provided to authenticate a session. To obtain an `auth_token`, see the [`/api/v1/authenticate` **POST** request](/developers/api/authentication/authenticate).

## Request

### Path parameters

- `endpointId` (double, required)

### Query parameters

- `per_page` (integer, optional, default: 25) — Number of detail rows to return per page.
- `page` (integer, optional, default: 1) — Page number to retrieve. Starts at `1`.
- `sort` (string, optional, default: -started_on) — Sorts detail rows by field value. Use `<operator><field>` format. Operators: `-` descending, `+` ascending. You can also combine multiple sort fields with commas (for example, `-started_on,destination_hostname`).
- `q` (string, optional) — Filters detail rows by field value. Use `<field>:<criteria>` format. Combine multiple filters with commas (for example, `protocol:TCP,destination_hostname:api.example.com`). Use `||` within one field for multiple values (for example, `protocol:TCP||UDP`). Supported keys: `destination_hostname`, `destination_ip`, `destination_port`, `protocol`, `flow_id`, `event_type`. Time window (optional, each as `<field>:<ISO-8601 UTC>`): * `started_from` - Lower bound on flow start * Defaults to 1 hour ago * Maximum look-back 30 days. * `started_until` - Upper bound on flow start * Defaults to now. * `completed_from` / `completed_until` - Bounds on flow completion time. Window fields must use `:` only (no other operators).

## Response

### 200

Detail rows for the requested filter window.

- `list of ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItems`

## Errors

### 400 Bad Request Error

The request is malformed. Common causes: - Invalid filter expression syntax in `q` - Invalid value for a filter or sort field - Datetime not in ISO-8601 format - Requested window exceeds the 30-day maximum

- `status_code` (integer, optional)
- `message` (string, optional)

### 401 Unauthorized Error

No token given.

- `message` (string, optional)

### 403 Forbidden Error

Caller lacks permission or the feature is not enabled for the organization.

- `status_code` (integer, optional)
- `message` (string, optional)

### 404 Not Found Error

Endpoint with ID \<number> not found.

- `status_code` (integer, optional)
- `message` (string, optional)

## Types

### ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItems

- `flow_id` (string, optional) — Unique identifier of the flow.
- `organisation_id` (integer, optional) — Identifier of the organization that owns the endpoint.
- `endpoint_id` (integer, optional) — Identifier of the endpoint the flow belongs to.
- `started_on` (string, optional) — Start time of the flow.
- `completed_on` (string, optional) — Completion time of the flow.
- `duration_seconds` (integer, optional) — Duration of the flow in seconds.
- `event_type` (string, optional) — Type of flow event (for example, `flow_start`, `flow_update`).
- `direction` (string, optional) — Direction of the flow (for example, `ingress`, `egress`).
- `source_ip` (string, optional) — Source IP address of the flow.
- `source_port` (integer, optional) — Source port of the flow.
- `destination_ip` (string, optional) — IP address of the destination.
- `destination_port` (integer, optional) — Destination port number.
- `protocol` (string, optional) — Transport protocol (for example, `TCP`, `UDP`).
- `bytes_up` (integer, optional) — Total bytes uploaded to the destination.
- `bytes_down` (integer, optional) — Total bytes downloaded from the destination.
- `destination_hostname` (string, optional, nullable) — Hostname of the destination, if resolved.
- `destination_hostname_source` (string, optional, nullable) — Source used to resolve the destination hostname (for example, `TLS_SNI`, `reverse_dns`).
- `nat_details` (ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsNatDetails, optional, nullable) — Network address translation details, if available.
- `pdp_context` (ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsPdpContext, optional, nullable) — PDP context information for the flow, if available.
- `release_details` (ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsReleaseDetails, optional, nullable) — Details about how the flow was released, if available.
- `session_id` (string, optional) — Identifier of the PDP session the flow belongs to.
- `last_loaded_at` (string, optional) — Time the flow record was last loaded.

### ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsNatDetails

Network address translation details, if available.

- `public_ip` (string, optional) — Public IP address used for the flow.

### ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsPdpContext

PDP context information for the flow, if available.

- `mcc` (string, optional) — Mobile country code.
- `mnc` (string, optional) — Mobile network code.
- `apn` (string, optional) — Access point name (APN) used for the PDP context.
- `imsi` (string, optional) — International Mobile Subscriber Identity of the SIM.
- `country` (ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsPdpContextCountry, optional) — Country associated with the network.
- `operator` (ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsPdpContextOperator, optional) — Mobile network operator associated with the PDP context.

### ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsReleaseDetails

Details about how the flow was released, if available.

- `release_side` (string, optional) — Side that released the flow (for example, `server`).
- `release_reason` (string, optional) — Reason the flow was released (for example, `tcp_fin`).

### ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsPdpContextCountry

Country associated with the network.

- `name` (string, optional) — Country name.
- `country_code` (string, optional) — International dialing code.
- `iso_code` (string, optional) — ISO country code.
- `id` (integer, optional) — Identifier of the country.

### ApiV1EndpointEndpointIdFlowlogsDetailGetResponsesContentApplicationJsonSchemaItemsPdpContextOperator

Mobile network operator associated with the PDP context.

- `id` (string, optional) — Identifier of the operator.
- `name` (string, optional) — Name of the operator.

## Examples

### Default - Last Hour

**Response**

```json
[
  {
    "flow_id": "7a3f1c9e84b2d05f6e1a8c47b9d23e60",
    "organisation_id": 100,
    "endpoint_id": 1,
    "started_on": "2026-05-11T13:42:17.000Z",
    "completed_on": "2026-05-11T13:58:04.000Z",
    "duration_seconds": 947,
    "event_type": "flow_start",
    "direction": "ingress",
    "source_ip": "10.0.0.5",
    "source_port": 51234,
    "destination_ip": "192.0.2.10",
    "destination_port": 443,
    "protocol": "TCP",
    "bytes_up": 18432,
    "bytes_down": 245760,
    "destination_hostname": "api.example.com",
    "destination_hostname_source": "TLS_SNI",
    "nat_details": {
      "public_ip": "203.0.113.4"
    },
    "pdp_context": {
      "mcc": "262",
      "mnc": "01",
      "apn": "em",
      "imsi": "262011234567890",
      "country": {
        "name": "Germany",
        "country_code": "49",
        "iso_code": "de",
        "id": 74
      },
      "operator": {
        "id": "26201",
        "name": "Telekom Deutschland"
      }
    },
    "release_details": {
      "release_side": "server",
      "release_reason": "tcp_fin"
    },
    "session_id": "pdp-9f3c1b27",
    "last_loaded_at": "2026-05-11T14:00:00.000Z"
  }
]
```

**SDK Code**

```python Default - Last Hour
import requests

url = "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript Default - Last Hour
const url = 'https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

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

```go Default - Last Hour
package main

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

func main() {

	url := "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

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

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

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

}
```

```ruby Default - Last Hour
require 'uri'
require 'net/http'

url = URI("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail")

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

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

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

```java Default - Last Hour
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Default - Last Hour
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp Default - Last Hour
using RestSharp;

var client = new RestClient("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Default - Last Hour
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

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()
```

### Filter by Destination IP

**Response**

```json
[
  {
    "flow_id": "b2e8d147a9c3f0526d8b41e7c5a09f3b",
    "organisation_id": 100,
    "endpoint_id": 1,
    "started_on": "2026-05-11T13:42:17.000Z",
    "completed_on": "2026-05-11T13:58:04.000Z",
    "duration_seconds": 947,
    "event_type": "flow_start",
    "direction": "ingress",
    "source_ip": "10.0.0.5",
    "source_port": 51234,
    "destination_ip": "111.1.124.234",
    "destination_port": 443,
    "protocol": "TCP",
    "bytes_up": 18432,
    "bytes_down": 245760,
    "destination_hostname": null,
    "destination_hostname_source": null,
    "nat_details": null,
    "pdp_context": null,
    "release_details": null,
    "session_id": "pdp-9f3c1b27",
    "last_loaded_at": "2026-05-11T14:00:00.000Z"
  }
]
```

**SDK Code**

```python Filter by Destination IP
import requests

url = "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail"

querystring = {"q":"destination_ip:111.1.124.234"}

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())
```

```javascript Filter by Destination IP
const url = 'https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A111.1.124.234';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

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

```go Filter by Destination IP
package main

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

func main() {

	url := "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A111.1.124.234"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

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

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

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

}
```

```ruby Filter by Destination IP
require 'uri'
require 'net/http'

url = URI("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A111.1.124.234")

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

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

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

```java Filter by Destination IP
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A111.1.124.234")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Filter by Destination IP
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A111.1.124.234', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp Filter by Destination IP
using RestSharp;

var client = new RestClient("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A111.1.124.234");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Filter by Destination IP
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A111.1.124.234")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

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()
```

### Filter by Destination Fields and Protocol

**Response**

```json
[
  {
    "flow_id": "4c1f9a72e6b3d85094f2a7c1e08b6d3f",
    "organisation_id": 100,
    "endpoint_id": 1,
    "started_on": "2026-05-11T13:42:17.000Z",
    "completed_on": "2026-05-11T13:50:00.000Z",
    "duration_seconds": 463,
    "event_type": "flow_start",
    "direction": "ingress",
    "source_ip": "10.0.0.5",
    "source_port": 51234,
    "destination_ip": "1.1.1.1",
    "destination_port": 6,
    "protocol": "TCP",
    "bytes_up": 1024,
    "bytes_down": 4096,
    "destination_hostname": "chat.cdn.whatsapp.net",
    "destination_hostname_source": "reverse_dns",
    "nat_details": null,
    "pdp_context": null,
    "release_details": null,
    "session_id": "pdp-9f3c1b27",
    "last_loaded_at": "2026-05-11T14:00:00.000Z"
  },
  {
    "flow_id": "4c1f9a72e6b3d85094f2a7c1e08b6d3f",
    "organisation_id": 100,
    "endpoint_id": 1,
    "started_on": "2026-05-11T13:50:00.000Z",
    "completed_on": "2026-05-11T13:58:04.000Z",
    "duration_seconds": 484,
    "event_type": "flow_update",
    "direction": "egress",
    "source_ip": "10.0.0.5",
    "source_port": 51234,
    "destination_ip": "1.1.1.1",
    "destination_port": 6,
    "protocol": "TCP",
    "bytes_up": 17408,
    "bytes_down": 241664,
    "destination_hostname": "chat.cdn.whatsapp.net",
    "destination_hostname_source": "reverse_dns",
    "nat_details": null,
    "pdp_context": null,
    "release_details": null,
    "session_id": "pdp-9f3c1b27",
    "last_loaded_at": "2026-05-11T14:00:00.000Z"
  }
]
```

**SDK Code**

```python Filter by Destination Fields and Protocol
import requests

url = "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail"

querystring = {"q":"destination_ip:1.1.1.1,destination_hostname:chat.cdn.whatsapp.net,destination_port:6,protocol:TCP"}

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())
```

```javascript Filter by Destination Fields and Protocol
const url = 'https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A1.1.1.1%2Cdestination_hostname%3Achat.cdn.whatsapp.net%2Cdestination_port%3A6%2Cprotocol%3ATCP';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

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

```go Filter by Destination Fields and Protocol
package main

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

func main() {

	url := "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A1.1.1.1%2Cdestination_hostname%3Achat.cdn.whatsapp.net%2Cdestination_port%3A6%2Cprotocol%3ATCP"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

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

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

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

}
```

```ruby Filter by Destination Fields and Protocol
require 'uri'
require 'net/http'

url = URI("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A1.1.1.1%2Cdestination_hostname%3Achat.cdn.whatsapp.net%2Cdestination_port%3A6%2Cprotocol%3ATCP")

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

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

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

```java Filter by Destination Fields and Protocol
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A1.1.1.1%2Cdestination_hostname%3Achat.cdn.whatsapp.net%2Cdestination_port%3A6%2Cprotocol%3ATCP")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Filter by Destination Fields and Protocol
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A1.1.1.1%2Cdestination_hostname%3Achat.cdn.whatsapp.net%2Cdestination_port%3A6%2Cprotocol%3ATCP', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp Filter by Destination Fields and Protocol
using RestSharp;

var client = new RestClient("https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A1.1.1.1%2Cdestination_hostname%3Achat.cdn.whatsapp.net%2Cdestination_port%3A6%2Cprotocol%3ATCP");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Filter by Destination Fields and Protocol
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://cdn.emnify.net/api/v1/endpoint/12345/flowlogs/detail?q=destination_ip%3A1.1.1.1%2Cdestination_hostname%3Achat.cdn.whatsapp.net%2Cdestination_port%3A6%2Cprotocol%3ATCP")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

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()
```