New API
The updated API is available through api2.marginalia-search.com.
Pass the API key in the API-Key header on every request. If you want to develop an integration but do not yet have a key, you can use the key public. Note that this key cannot create custom filters, and often hits a rate limit.
Obtaining a key
Free non-commercial
Email contact@marginalia-search.com. The email step is necessary to prevent mass signup abuse.
Provided under CC-BY-NC-SA 4.0.
Paid non-commercial
Buy a non-commercial key to skip the line and support the search engine with a one-time payment. Optional, and will always remain optional.
Provided under CC-BY-NC-SA 4.0.
Commercial
Buy a metered commercial key with no commercial usage restriction or attribution requirement.
Manage your subscription at polar.sh/marginalia-search/portal.
Other terms are negotiable, email contact@marginalia-search.com .
Getting started
A test request using the public key:
$ curl -H"API-Key: ${API_KEY}" -XGET https://api2.marginalia-search.com/search?query=json+api
The following query parameters are understood.
| Param | Value | Description |
| count | 1-100 | Number of results |
| timeout | 50-250 | Query execution timeout (ms) |
| dc | 1-100 | Max number of results per domain |
| page | int | Select results page (1-indexed) |
| 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
You can set up custom filters for your API key. This is not allowed on the public key.
| 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 in XML. These can be 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)
The deprecated API is available through api.marginalia.nu or api.marginalia-search.com. Both endpoints are equivalent and will work as long as the project does, but will not receive new functionality.
Examples:
https://api.marginalia.nu/public/
https://api.marginalia.nu/public/search/json+api
https://api.marginalia.nu/public/search/json+api?count=10
The key public is available for experimentation, as used in the examples above. This key has a shared rate limit across all consumers; when the limit is hit, HTTP 503 is returned.
Query parameters (deprecated)
| Param | Value | Description |
| count | int | Number of results |
| dc | int | Max number of results per domain |
| page | int | Select results page (1-indexed) |
| 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?
Let me know if there are features you would like added to the API.