New API
The updated API for the search engine is available through api2.marginalia-search.com.
For all requests, pass the API-Key using the API-key header. If you want to develop an integration, but do not yet have an API key,
you can use the API key public. Note that it is blocked from creating custom filters, and very often hits a rate limit.
Obtaining a Key
Please send an email to contact@marginalia-search.com if you want your own key with a separate rate limit. The search engine has seen quite a lot of problems with bot abuse, making this registration step a sad necessity.
By default the data is provided under the CC-BY-NC-SA 4.0 license. Other licensing and terms are negotiable.
Getting Started
To make a test request using the public sample key, which is very often overloaded, you can for example call
$ curl -H"API-Key: ${API_KEY}" -XGET https://api2.marginalia-search.com/search?query=json+api
These query parameters are understood
| Param | Value | Description |
| count | int | Number of Results |
| dc | int | Max number of results per domain |
| nsfw | 0 | no filter |
| nsfw | 1 | (experimental) reduce extreme results | filter | string | Use custom filter |
Sample code in Python 3
import requests
url = "https://api2.marginalia-search.com/search?query={query}";
rsp = requests.get(url.format(query="linear b"), headers={'API-Key': 'public'});
if rsp.ok:
data = rsp.json()
print ("Query: ", data['query'])
print ("License: ", data['license'])
print ("")
for result in data['results']:
print (result['url'])
print ("\t" + result['title'])
print ("\t" + result['description'])
print ("")
else:
print ("Bad Status " + str(rsp.status_code))
Filters
It is possible to set up custom filters for your API key. This is not allowed on the public key,
using these API endpoints.
| Method | Endpoint | Description |
| GET | /filter | List configured filters |
| POST | /filter/NAME | Create a new filter, NAME. |
| GET | /filter/NAME | Retrieve filter definition for NAME |
| DELETE | /filter/NAME | Delete custom filter NAME |
Custom filters are defined using an XML format. These XML files can be either hand rolled, or generated by the filter editor.
XML example
<?xml version="1.0"?>
<filter>
<domains-include>
www.google.com
*.youtube.com
</domains-include>
<domains-exclude>
www.yandex.ru
</domains-exclude>
<domains-promote amount="-1.0">
www.bing.com
www.yahoo.com
</domains-promote>
<!-- Adjust ranking of these terms -->
<domains-promote amount="1.0">
www.mojeek.com
</domains-promote>
<temporal-bias>OLD</temporal-bias> <!-- or RECENT, or NONE -->
<terms-require>
foo
bar
</terms-require>
<terms-exclude>
baz
</terms-exclude>
<!-- Adjust ranking of these terms -->
<terms-promote amount="5.0">
quux
</terms-promote>
<!-- estimated publication year (janky) -->
<limit param="year" type="lt" value="1996" />
<!-- a measure of how much javascript is on the page,
legacy marginalia search ranking metric -->
<limit param="quality" type="eq" value="5" />
<!-- how many documents are on the domain -->
<limit param="size" type="gt" value="100" />
<!-- pagerank, 0-255 -->
<limit param="rank" type="gt" value="20" />
</filter>
Old API (DEPRECATED)
A deprecated API for the search engine is available through api.marginalia.nu, or api.marginalia-search.com. Both endpoints are equivalent and will work as long as the project does, though will not receive new functionality.
The API is simple enough to be self-explanatory. Examples:
https://api.marginalia.nu/public/
https://api.marginalia.nu/public/search/json+api
https://api.marginalia.nu/public/search/json+api?count=10
For experimentation, the key “public” is available, as used in the examples on this page. This key has a shared rate limit across all consumers. When this rate limit is hit a HTTP status 503 is returned.
Query Parameters (DEPRECATED)
| Param | Value | Description |
| count | int | Number of Results |
| dc | int | Max number of results per domain |
| nsfw | 0 | no filter |
| nsfw | 1 | (experimental) reduce extreme results |
| index | int | deprecated |
Sample code in python 3 (DEPRECATED)
import requests
url = "https://api.marginalia.nu/{key}/search/{query}";
rsp = requests.get(url.format(key='public', query="linear b"));
if rsp.ok:
data = rsp.json()
print ("Query: ", data['query'])
print ("License: ", data['license'])
print ("")
for result in data['results']:
print (result['url'])
print ("\t" + result['title'])
print ("\t" + result['description'])
print ("")
else:
print ("Bad Status " + str(rsp.status_code))
Something missing?
Please let me know if there are features you would like added to the API.