POST Query

POST Query


Request used to Query your Log entries using a LEQL query. Multiple logs can be queried in a POST request.

URL

https://REGION.rest.logs.insight.rapid7.com/query/logs/

REGION is the data center where your account is - e.g. "us" or "eu".

Method:

POST

Authentication:

Read Only key or above is required. See: REST API Authentication

Data Params

1
{
2
"logs": [
3
"34634d9e-89e8-4e02-a255-f10baf0e9f2b",
4
"34634d9e-89e8-4e02-a255-f10baf0e9f2b"
5
],
6
"leql": {
7
"during": {
8
"from": 1432080000000,
9
"to": 1432090000000
10
},
11
"statement": "where(/.*/)"
12
}
13
}
ParamAboutRequiredExample
logsList of log keysTrue`"logs": ["34634d9e-89e8-4e02-a255-f10baf0e9f2b","34634d9e-89e8-4e02-a255-f10baf0e9f2b"],
statementa valid LEQL query to run against the logTruequery=where(foo=bar)
fromlower bound of the time range you want to query against; UNIX timestamp in millisecondsTruefrom=1450557604000
tolower bound of the time range you want to query against; UNIX timestamp in millisecondsTrueto=1460557604000

Success Response:

Code: 200 for a successful queryContent:

json
1
{
2
"logs": ["f9c6e2c1-ac7a-4a29-8faa-a8d70f96df70"],
3
"statistics": {...},
4
"leql": {
5
"statement": "where(something) calculate(count)",
6
"during": {
7
"from": 1,
8
"to": 10000
9
}
10
}
11
}

Code: 202 for a query that successfully started but has not yet finishedContent:

json
1
{
2
"logs": [
3
"f9c6e2c1-ac7a-4a29-8faa-a8d70f96df70"
4
],
5
"id": "deace1fd-e605-41cd-a45c-5bf1ff0c3402-1",
6
"query": {
7
"statement": "where(foo) calculate(count:x)",
8
"during": {
9
"to": 100000,
10
"from": 100
11
}
12
},
13
"links": [{
14
"rel": "self",
15
"href": "https://us.rest.logs.insight.rapid7.com/query/deace1fd-e605-41cd-a45c-5bf1ff0c3402-1"
16
}]
17
}

Long-running queries:

Depending on the size of the underlying dataset of the complexity of the query, a request may not yield a value straight away. In this case a well-formed query will return an HTTP 202 response and an ID you can use to check its state.

An example response would look like this:

1
{
2
"logs": [
3
"f9c6e2c1-ac7a-4a29-8faa-a8d70f96df70"
4
],
5
"id": "deace1fd-e605-41cd-a45c-5bf1ff0c3402-1",
6
"query": {
7
"statement": "where(foo) calculate(count:x)",
8
"during": {
9
"to": 100000,
10
"from": 100
11
}
12
},
13
"links": [{
14
"rel": "self",
15
"href": "https://us.rest.logs.insight.rapid7.com/query/deace1fd-e605-41cd-a45c-5bf1ff0c3402-1"
16
}]
17
}

You can poll this query for a value by issuing a GET request with the link returned in the response, e.g. curl https://us.rest.logs.insight.rapid7.com/query/deace1fd-e605-41cd-a45c-5bf1ff0c3402-1 -H 'x-api-key: 8e61d125-85f6-450b-a344-82c092477cf1'.

The endpoint /query/ will give one of the following responses:

  • A HTTP 200 status and a response containing a value (list of events or statistical results as above) if the query completed
  • A HTTP 202 status and a response containing an ID and links to continue polling if the query is still in progress. The response will look like this:
1
{
2
"id": "deace1fd-e605-41cd-a45c-5bf1ff0c3402-0",
3
"links": [{
4
"rel": "self",
5
"href": "https://us.rest.logs.insight.rapid7.com/query/deace1fd-e605-41cd-a45c-5bf1ff0c3402-0"
6
}]
7
}

There is no limit on how frequently you can poll a query, or how many times you may poll it. However, if you do not poll a query resource for 20 seconds, it will expire. Subsequent calls to that resource will return a 404.

Error Response:

  • Code: 400 for bad user input`

  • Code: 404 for a resource that was badly formed or could not be found

  • Code: 500 for any internal error, for example if the query could not be executed

Sample Call:

Python
1
import requests
2
import json
3
4
def continue_request(req):
5
if 'links' in req.json():
6
continue_url = req.json()['links'][0]['href']
7
new_response = fetch_results(continue_url)
8
handle_response(new_response)
9
10
def fetch_results(provided_url):
11
"""
12
Make the get request to the url and return the response.
13
"""
14
try:
15
print provided_url
16
response = requests.get(provided_url, headers={'x-api-key': '00112233-4455-6677-8899-aabbccddeeff
17
'})
18
return response
19
except requests.exceptions.RequestException as error:
20
print error
21
22
def handle_response(resp):
23
response = resp
24
if response.status_code >= 200:
25
if 'events' in response.json():
26
json.dumps(response.json(), indent=4, separators={':', ';'})
27
if 'links' in response.json():
28
continue_request(resp)
29
else:
30
print json.dumps(response.json(), indent=4, separators={':', ';'})
31
else:
32
print 'Error status code ' + str(response.status_code)
33
return
34
35
def post_query(url=None):
36
uri = url
37
body = None
38
if not url:
39
body = {"logs": ["9d1caf16-7b23-48f0-8ab9-ff9f2de2c323", "a4324dbd-d7cc-40e3-a766-2e260d0b1b57"],
40
"leql": {"during": {"from": 1471343082000, "to": 1471344282000}, "statement": "where(/.*/) calculate(count)"}}
41
uri = 'https://us.rest.logs.insight.rapid7.com/query/logs/'
42
headers = {'x-api-key': '951b36be-ceb5-476e-8eaa-ac33cd23ba58'}
43
print uri
44
r = requests.post(uri, json=body, headers=headers)
45
handle_response(r)
46
print r.status_code, r.content
47
48
if __name__ == '__main__':
49
post_query()

Notes:

  • The maximum supported length of the URL is 8192 characters
  • Pagination is only supported with 'where' queries only
  • The maximum page size is currently limited to 500 log entries
  • There is no limit on how frequently you can poll a query, or how many times you may poll it. However, if you do not poll a query resource for 20 seconds, it will expire. Subsequent calls to that resource will return a 404.