Web API Reference
This API is implemented in Wolfram Language and wired through
AppExtensions' HTTP handler. All endpoints live under/api/….
TLDR;
-
Base URL:
/api/ -
Auth: none
-
CORS:
Access-Control-Allow-Origin: *(enabled by the server) -
Formats:
- Requests: JSON in the body for most endpoints
- Responses: JSON (often simple strings/booleans), HTTP
200on success - Errors: HTTP
409with a JSON string message (e.g."Notebook is missing")
Index endpoint
GET /api/
Returns the top‑level groups available on this server.
Response — 200 OK
[
"/api/kernels/",
"/api/transactions/",
"/api/frontendobjects/",
"/api/extensions/",
"/api/ready/",
"/api/notebook/",
"/api/alphaRequest/"
]
Readiness
GET /api/ready/
Health check.
Response — 200 OK
{"ReadyQ": true}
Wolfram|Alpha passthrough
POST /api/alphaRequest/
Run a Wolfram|Alpha query and return its ShortAnswer.
Request body
{ "Query": "integrate x^2" }
Response — 200 OK
"x^3/3"
Errors (e.g., malformed body) come back as HTTP 409 with a JSON string message.
Notebook API
GET /api/notebook/
Returns the available subroutes:
[
"/api/notebook/list/",
"/api/notebook/create/",
"/api/notebook/create/pull/",
"/api/notebook/cells/"
]
GET /api/notebook/list/
List known notebooks.
Response — 200 OK
[
{ "Id": "<hash>", "Opened": true, "Path": "/path/to.nb" },
{ "Id": "<hash>", "Opened": false, "Path": "/path/other.nb" }
]
POST /api/notebook/create/
Create a new notebook in the active UI session.
Prerequisites
- A UI window must be open
Response — 200 OK
"<createUid>"
The returned createUid is a temporary id used to pull the real notebook id.
POST /api/notebook/create/pull/
Exchange the temporary createUid for the new notebook’s hash.
Request body
{ "Id": "<createUid>" }
Response — 200 OK
"<notebookId>"
The server pushes the notebook hash to an internal queue when the UI actually creates it. Poll this endpoint until it resolves.
Notebook cells
GET /api/notebook/cells/ returns the following subroutes:
[
"/api/notebook/cells/list/",
"/api/notebook/cells/get/",
"/api/notebook/cells/focused/",
"/api/notebook/cells/set/",
"/api/notebook/cells/add/",
"/api/notebook/cells/evaluate/",
"/api/notebook/cells/project/",
"/api/notebook/cells/delete/"
]
POST /api/notebook/cells/list/
List cells in a notebook.
Request body
{ "Notebook": "<notebookHash>" }
Response — 200 OK
[
{ "Id": "<cellId>", "Type": "Input", "State": "…", "Display": "codemirror" },
{ "Id": "<cellId>", "Type": "Output", "State": "…", "Display": "html" }
]
Errors — 409 with "Notebook is missing" when the id is unknown.
POST /api/notebook/cells/focused/
Get the focused cell (or the last cell if none is focused).
Request body
{ "Notebook": "<notebookHash>" }
Response — 200 OK
{ "Id": "<cellId>", "Type": "Input", "State": "…", "Display": "codemirror" }
POST /api/notebook/cells/get/
Fetch a cell’s raw Data.
Request body
{ "Cell": "<cellId>" }
Response — 200 OK
"(* the cell's content as a string or JSON-encoded expression *)"
POST /api/notebook/cells/delete/
Delete a cell.
Request body
{ "Cell": "<cellId>" }
Response — 200 OK
"Removed"
POST /api/notebook/cells/set/
Update a cell’s Data field. If the notebook UI is open, the change is applied live.
Request body
{ "Cell": "<cellId>", "Data": "…new content…" }
Responses — 200 OK
"Data field was updated live in the notebook"
or
"Data field was updated"
Errors — 409 with "Cannot edit output cells" when editing is disallowed for that cell.
POST /api/notebook/cells/add/
Add a new Input cell to a notebook.
Request body
{
"Notebook": "<notebookHash>",
"Data": "…initial content…",
"Id": "<optionalCellId>",
"After": "<optionalcellIdToInsertAfter>"
}
Response — 200 OK
"Added to the end of the notebook"
—or—
"Added after <cellId>"
POST /api/notebook/cells/evaluate/
Evaluate a cell in an open notebook UI.
Request body
{ "Cell": "<cellId>" }
Response — 200 OK
"Submitted"
Errors — 409 with "Can't evaluate cell in a closed notebook. Use transactions".
POST /api/notebook/cells/project/
Project/evaluate a cell (variant of evaluate/).
Request body
{ "Cell": "<cellId>" }
Responses — 200 OK
"Evaluation started"
Errors — 409 with "Can't evaluate cell in a closed notebook".
Frontend Objects
GET /api/frontendobjects/
[ "/api/frontendobjects/get/" ]
POST /api/frontendobjects/get/
Resolve a frontend object by UId. This is a two‑phase poll:
- First call returns
{ "Resolved": false }and kicks off resolution in a ready kernel. - Poll until you receive
{ "Resolved": true, "Data": "<ExpressionJSON string>" }.
Request body
{
"UId": "<objectId>",
"Kernel": "<optionalKernelHash>"
}
Responses — 200 OK
{ "Resolved": false }
—or—
{ "Resolved": true, "Data": "{\"…ExpressionJSON…\"}" }
Errors — 409 with messages like "Kernel is missing" when no suitable kernel is available.
Transactions API
Batch/evaluate code without an open notebook via transactions.
GET /api/transactions/
[
"/api/transactions/create/",
"/api/transactions/get/",
"/api/transactions/delete/",
"/api/transactions/list/"
]
POST /api/transactions/create/
Create and submit a transaction to a specific kernel.
Request body
{
"Kernel": "<kernelHash>",
"Data": "(* Wolfram Language code or serialized input *)"
}
Response — 200 OK
"<transactionHash>"
Errors — 409 with "Kernel is missing".
POST /api/transactions/get/
Fetch transaction status and results.
Request body
{ "Hash": "<transactionHash>" }
Response — 200 OK
{
"Hash": "<transactionHash>",
"State": "Evaluation" | "Idle" | "Error" | "Undefined",
"Result": [
{ "Data": "…", "Type": "Output", "Display": "codemirror" },
{ "Data": "…", "Type": "Output", "After": "<cellId>", "Display": "html" }
]
}
- Each result is appended as the transaction emits outputs. If the producer attaches a
Metaobject, its keys are merged into the result.
POST /api/transactions/list/
List transactions (id + coarse state).
Response — 200 OK
[
{ "Hash": "<tx>", "State": "Idle" },
{ "Hash": "<tx>", "State": "Evaluation" }
]
POST /api/transactions/delete/
Delete a finished/obsolete transaction.
Request body
{ "Hash": "<transactionHash>" }
Response — 200 OK
true
Kernels API
Manage and query kernels, and make asynchronous function calls.
GET /api/kernels/
[
"/api/kernels/list/",
"/api/kernels/restart/",
"/api/kernels/abort/",
"/api/kernels/get/",
"/api/kernels/create/",
"/api/kernels/unlink/",
"/api/kernels/init/",
"/api/kernels/deinit/",
"/api/kernels/fetch/"
]
GET /api/kernels/list/
List available kernels.
Response — 200 OK
[
{
"Hash": "<kernelHash>",
"State": "…",
"ReadyQ": true,
"Name": "WolframKernel",
"ContainerReadyQ": true
}
]
POST /api/kernels/get/
Get one kernel by hash.
Request body
{ "Hash": "<kernelHash>" }
Response — 200 OK — same shape as items in list/.
POST /api/kernels/restart/
Restart a kernel.
Request body
{ "Hash": "<kernelHash>" }
Response — 200 OK
true
POST /api/kernels/abort/
Abort the current evaluation on a kernel.
Request body
{ "Hash": "<kernelHash>" }
Response — 200 OK
true
POST /api/kernels/init/
Initialize a kernel with environment settings.
Request body
{ "Hash": "<kernelHash>" }
Response — 200 OK
true
POST /api/kernels/deinit/
De‑initialize a kernel.
Request body
{ "Hash": "<kernelHash>" }
Response — 200 OK
true
Asynchronous function calls (fetch/)
POST /api/kernels/fetch/
Call a Wolfram Language symbol with arguments asynchronously in a ready kernel.
Request body
{
"Symbol": "Package`FunctionName",
"Args": [ /* positional args */ ],
"Kernel": "<optionalKernelHash>"
}
Response — 200 OK
"<requestUid>"
POST /api/kernels/fetch/get/
Poll for the result of a prior fetch/.
Request body
{ "UId": "<requestUid>" }
Responses — 200 OK
{ "ReadyQ": false }
—or—
{ "ReadyQ": true, "Result": "{\"…ExpressionJSON…\"}" }
Errors — 409 with "UId is not provided or is missing".
If the target function returns a
Promiseon the kernel side, the API resolves that promise and returns itsExpressionJSONpayload when ready.
Not implemented
POST /api/kernels/create/→409"Not implemented"POST /api/kernels/unlink/→409"Not implemented"
Extensions & CDN
These endpoints help you discover and load WLJS extensions and styles.
GET /api/cdn/
[
"/api/cdn/list/",
"/api/cdn/get/js/",
"/api/cdn/get/styles/"
]
POST /api/cdn/get/js/
Return a list of CDN URLs for the requested packages’ JavaScript (plus required shims).
Request body — array of package keys
["wljs-some-package", "..." ]
Response — 200 OK
[
"https://cdn.skypack.dev/twind/shim",
"https://cdn.jsdelivr.net/gh/<repo>@<branch>/<path>.js",
"https://cdn.jsdelivr.net/gh/<this-repo>@<branch>/assets/polyfill.js"
]
GET /api/cdn/get/styles/
Return a list of CDN URLs for stylesheets, including the built‑in minimal theme.
Response — 200 OK
[
"https://cdn.jsdelivr.net/gh/<this-repo>@<branch>/assets/minimal.css"
]
GET /api/cdn/list/
List all enabled packages that expose a minjs entry.
Response — 200 OK
[ "wljs-foo", "wljs-bar", "…" ]
GET /api/extensions/
[
"/api/extensions/list/",
"/api/extensions/get/minjs/",
"/api/extensions/bundle/minjs/",
"/api/extensions/get/styles/",
"/api/extensions/bundle/styles/"
]
GET /api/extensions/list/
Discover enabled extensions and versions.
Response — 200 OK
[
{ "name": "wljs-foo", "version": "1.2.3" },
{ "name": "common-css", "version": "0.1" }
]
POST /api/extensions/get/minjs/
Return URL‑encoded source blobs for each package’s minjs payload (not URLs).
Request body — array of package keys (the special "common-css" key is ignored here)
["wljs-foo", "wljs-bar"]
Response — 200 OK
[ "function(){…}%7D", "(function(){…})%3B" ]
POST /api/extensions/bundle/minjs/
Return a single URL‑encoded JS bundle that concatenates all enabled packages’ minjs payloads.
Response — 200 OK
"/* wljs-api bundler */%0D%0A%7B%0D%0A…%0D%0A%7D"
POST /api/extensions/get/styles/
Return URL‑encoded CSS blobs for each requested package’s styles. If the list includes "common-css", the server also appends its built‑in common.css.
Request body
["wljs-foo", "common-css"]
Response — 200 OK
[ "body%7B…%7D", "/*common*/%0A…" ]
POST /api/extensions/bundle/styles/
Return a single URL‑encoded CSS bundle of all enabled packages’ styles plus the built‑in common styles.
Response — 200 OK
".class%7B…%7D%0A%0A/*common*/%0A…"
Some packages are blacklisted from the JS bundle by design (e.g.
wljs-markdown-support,wljs-plotly,wljs-mermaid-support, etc.).
Error handling
- Success → HTTP
200, JSON body (may be a string or boolean) - Failure → HTTP
409, body is a JSON string with the message (e.g.,"Kernel is missing").
Common messages include:
"Notebook is missing","Cell is missing""Kernel is missing"or"Kernel is missing or not ready""Cannot edit output cells""Can't evaluate cell in a closed notebook. Use transactions""Not implemented"
Types & fields
- Ids are opaque hashes:
Notebook→Id,Cell→Id,Kernel→Hash,Transaction→Hash, async request/resolve ids →UId. - Kernel fields:
State(string),ReadyQ(boolean),ContainerReadyQ(boolean),Name(string) - Transaction fields:
Stateis one of"Evaluation" | "Idle" | "Error" | "Undefined";Resultis a list of output objects with at leastDataandType("Output"). Optional keys:Display,After,Before, custom meta. - Cell fields:
Typeis typically"Input"or"Output";Displayhints at rendering (e.g."codemirror","html").
Examples
See this notebook: WebAPI Notebook.wln
Notes & caveats
- Consider
hash=id
- Many endpoints require a ready kernel or an opened notebook; otherwise you’ll receive a
409with a helpful message. - Some responses intentionally return URL‑encoded source blobs instead of URLs (extensions/styles). Decode on the client if you plan to inline them.
- The server sets
Content-Length,Connection: Keep-Alive, and CORS headers on responses. - There are a few implementation quirks (e.g., cell‑editing rules and insertion logic) that may change; rely on the messages the server returns.