REST API
Call ScholarMuse tools over HTTPS with an API key, for scripts and tools that do not use MCP.
Most people connect an agent and never need this page. The REST API is for scripts, notebooks and tools that cannot connect through MCP. It runs the same tools, with the same discipline packs and the same credits.
Authentication
Send your API key with every call, in the Authorization header:
Authorization: Bearer <key>You can also send the key in an x-api-key header instead.
Create and delete keys in your account settings, under API Keys. A key starts with sm_ and is shown in full only once, when you create it, so copy it then. Treat a key like a password: do not share it or put it in public code. If a key leaks, delete it and create a new one.
Each key can send 60 requests per minute. Beyond that the API answers 429 with a Retry-After header.
Run a tool
Send a POST request to /api/v1/<tool>, where <tool> is the tool name, with the tool's arguments as a JSON body.
curl -X POST https://scholarmuse.ai/api/v1/search_papers \
-H "Authorization: Bearer $SCHOLARMUSE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "microplastics in agricultural soil",
"year_from": 2020,
"open_access_only": true,
"limit": 5
}'The same call in Python:
import os
import requests
response = requests.post(
"https://scholarmuse.ai/api/v1/search_papers",
headers={"Authorization": f"Bearer {os.environ['SCHOLARMUSE_API_KEY']}"},
json={"query": "microplastics in agricultural soil", "year_from": 2020, "limit": 5},
timeout=60,
)
response.raise_for_status()
for record in response.json()["records"]:
print(record["title"], record["url"])See what a tool accepts
Send a GET request to the same address to get the tool's name, title, description, discipline pack and the JSON Schema of its arguments (input_schema).
curl https://scholarmuse.ai/api/v1/search_papersGET /api/v1 lists every tool, and /api/v1/openapi.json describes the whole API in OpenAPI 3.1. These three addresses need no API key. The API reference shows every tool and its arguments on one page.
The list_capabilities tool returns every capability with its tool names, pack and sources.
Response
A successful call returns HTTP 200 with a JSON object.
| Field | Meaning |
|---|---|
summary | One sentence describing the result |
records | The list of results. See below |
partial | true when some sources failed but others answered |
failedSources | The sources that failed, each with source and error |
files | Files produced by the call, each with name, url and mimeType |
credits_used | Credits charged for this call |
call_id | The identifier of this call |
Fields that do not apply to a call are left out. For example, partial and failedSources appear only when a source failed, and files only when the call produced a file. Some tools add an extra object with tool-specific details; the figure tools use it for figure_id and status.
Each item in records has the same shape:
| Field | Meaning |
|---|---|
id | Identifier of the record, prefixed with the source |
type | Kind of record, for example a paper |
source | The source the record came from |
title | Title, when there is one |
url | Address of the record at the source, when there is one |
license | Licence of the source's data |
attribution | Attribution line for the source |
retrievedAt | When the record was fetched, as an ISO 8601 date and time |
data | The record's fields, which differ by tool |
Example, shortened:
{
"summary": "…",
"records": [
{
"id": "openalex:…",
"type": "…",
"source": "openalex",
"title": "…",
"url": "https://…",
"license": "…",
"attribution": "…",
"retrievedAt": "2026-10-12T09:30:00.000Z",
"data": { "doi": "…" }
}
],
"call_id": "…"
}Errors
Errors return a JSON object with a code and a readable message:
{ "error": { "code": "invalid_input", "message": "…" } }| HTTP status | Code | Meaning |
|---|---|---|
400 | invalid_input | The arguments do not match the tool's schema. The message names the fields |
401 | unauthorized | The API key is missing or not valid |
402 | insufficient_credits | Not enough credits for this call |
403 | pack_disabled | The tool's discipline pack is switched off for your account. Switch it on at Capability packs |
404 | unknown_tool | There is no tool with this name |
429 | rate_limited | Too many requests with this key. Wait for the number of seconds in the Retry-After header |
502 | upstream_error | The tool could not complete, for example because no source answered |
500 | internal | Something unexpected went wrong on our side |
A call that returns an error is not charged.
Figures over REST
Figures are drawn in the background. create_figure and edit_figure return either the finished image in files, or extra.status set to pending together with extra.figure_id. The cost of a figure is charged when the image is finished, so for these tools the top-level credits_used is 0 and the finished result reports the figure's credits in extra.credits_used. If the status is pending, call get_figure with the figure_id about 30 seconds later, and repeat until the image is ready. See Scientific figures.