SumWise Compute private alpha
REST developer documentation
Integrate with SumWise-hosted deterministic computation through one documented HTTPS operation. Send one mathematical expression and receive a closed integer, rational, or finite approximate-real result.
Private-alpha contract status
This is the current private-alpha v1 integration reference. The contract remains a Draft candidate and carries no public-availability or service-level guarantee. Authorized credentials, limits, evaluation duration, and support terms are communicated separately.
HTTPS endpoint and authentication
POST https://api.sumwisecalc.com/v1/evaluate
- HTTPS is required. No HTTP endpoint or HTTP-to-HTTPS redirect is promised.
- The path and method are case-sensitive, and the query string must be empty.
- Send
Content-Type: application/json, optionally with the sole unquoted parametercharset=utf-8. - Send one complete UTF-8 body with one valid
Content-Length. Transfer-encoded requests are not accepted. - Success uses
application/json; deliverable errors useapplication/problem+json.
Put the issued opaque key in exactly one header:
Authorization: Bearer <api-key>
Treat the key as a secret. Keep it in a server-side secret store or environment variable, never in a URL, request body, browser application, log, or source file. Missing, malformed, unknown, disabled, revoked, and expired keys all produce HTTP 401 with authentication_required.
Request schema
{"expression":"mean(10,20,30)"}
The body is a closed JSON object with exactly one case-sensitive member. expression is required and must be a string. Duplicate, additional, misspelled, escaped-name, and wrong-case members are rejected. After JSON escape decoding, the expression must remain ASCII and must satisfy the grammar below.
Expression grammar
expression := additive
additive := multiplicative ( ("+" | "-") multiplicative )*
multiplicative := unary ( ("*" | "/") unary )*
unary := ("+" | "-") unary | primary
primary := number | constant | function-call | "(" expression ")"
function-call := function-name "(" expression ("," expression)* ")"
Addition/subtraction and multiplication/division evaluate left to right; parentheses override precedence. Function arguments are comma-separated expressions and may nest admitted calls.
(digits ["." [digits]] | "." digits) ["e" ["+" | "-"] digits]
Examples are 12, 12.34, .5, 1., 1e6, and 3.2e-5. A leading sign is a unary operator. Lowercase e is the supported exponent marker. Integer tokens are exact; decimal-point and scientific tokens are approximate binary64 inputs.
The case-sensitive constants pi, e, tau, and phi produce approximate reals. Space, tab, carriage return, and line feed may separate tokens. Explicit * is required; exact rationals use expressions such as 7/6. Variables, assignments, implicit multiplication, user functions, data containers, complex results, and symbolic results are unavailable.
Current supported functions
Names are case-sensitive and have no aliases. Only the following nine functions are admitted.
| Function | Arity | Behavior |
|---|---|---|
sum(...) | 1–30 | Reduces once in written left-to-right order. |
mean(...) | 1–30 | Computes that sum and divides by the exact positive argument count. |
min(...) | 1–30 | Selects the least argument; equal values select the first occurrence. |
max(...) | 1–30 | Selects the greatest argument; equal values select the first occurrence. |
abs(x) | 1 | Returns the nonnegative magnitude of a real scalar. |
sign(x) | 1 | Returns -1, 0, or 1 in the input's exact or approximate family. |
floor(x) | 1 | Returns the greatest integer no larger than x. |
ceil(x) | 1 | Returns the least integer no smaller than x. |
trunc(x) | 1 | Returns the integer toward zero. |
Each argument must evaluate to an admitted scalar integer, rational, or finite approximate real. Function names not listed above are not part of this profile.
Exactness, precision, and rendering
- Arithmetic over exact integers and rationals stays exact. Results are canonical integers or reduced rationals with a positive denominator.
mean(1,2)returns exact rational3/2, not a floating approximation.- Decimal/scientific literals and approximate constants introduce IEEE-754 binary64 provenance. Approximate results remain approximate even when they look integral.
minandmaxcompare exact values exactly; approximate participation uses the finite-real comparison path while preserving the selected argument's family.- The five scalar utilities preserve exact input and approximate provenance. They normalize an approximate zero result to positive zero.
- Successful approximate results are finite; NaN and infinity are not successful result values.
The API does not provide selectable decimal precision, currency rounding, or a configurable rounding mode. Approximate text is locale-independent, uses a dot decimal separator and lowercase e, and round-trips to the same binary64 value in the qualified build. Positive zero is "0" and negative zero is ordinarily "-0". Cross-toolchain byte-for-byte equality of approximate text is not frozen.
Result schemas
Every success body is closed to ok, api_version, operation, engine_version, and result. Numeric values are strings, not JSON number tokens.
Integer
{"type":"integer","text":"55","exactness":"exact","value":"55"}
Rational
{"type":"rational","text":"3/2","exactness":"exact","value":{"numerator":"3","denominator":"2"}}
Approximate real
{"type":"real","text":"3.141592653589793","exactness":"approximate","value":"3.141592653589793"}
Public limits
| Boundary | Contract |
|---|---|
| Complete request body | At most 4,096 UTF-8 bytes, inclusive |
| Request shape | Exactly one expression string; no batch members |
| Aggregation functions | 1 through 30 arguments |
| Scalar utility functions | Exactly 1 argument |
| Per-key concurrency | A concurrent request for a key can be rejected with HTTP 429 |
| Rate and quota quantities | Credential-specific and communicated separately |
A durably accepted request consumes one rate attempt and is not later refunded. Additional expression, token, node, nesting, work, time, and result limits fail closed; their numeric values are not external contract values. Limit exhaustion never returns a truncated success.
Errors and retries
Deliverable service problems are closed to type, title, status, detail, and code. Compute evaluation problems additionally include "api_version":"v1" and "operation":"evaluate". Branch on stable status/code pairs rather than message text.
| Status | Codes |
|---|---|
| 400 | invalid_http_request |
| 401 | authentication_required |
| 404 | route_not_found |
| 405 | method_not_allowed |
| 411 | content_length_required |
| 413 | request_body_too_large |
| 415 | unsupported_media_type |
| 422 | invalid_request, expression_parse_error, unbound_symbol, unknown_function, operation_not_allowed, unsupported_expression, domain_error, numeric_overflow, computation_limit_exceeded, result_limit_exceeded |
| 429 | concurrent_request_limit_exceeded, rate_limit_exceeded, quota_exhausted |
| 500 | internal_error |
| 503 | service_busy, service_unavailable |
| 504 | computation_timeout |
Complete responses carry Cache-Control: no-store, X-Content-Type-Options: nosniff, and an opaque X-Request-Id. HTTP 405 includes Allow: POST; HTTP 401 includes WWW-Authenticate: Bearer realm="SumWise Compute". A transport failure is not necessarily a serialized service problem.
- Correct request, authentication, expression, domain, or limit errors before retrying.
- For
rate_limit_exceededandquota_exhausted, wait at least the returned positiveRetry-Afterdelta-seconds. - Serialize work for a key instead of retrying
concurrent_request_limit_exceededwhile another request remains active. - Bounded backoff may be used for service-busy/unavailable or transient transport failure, but no retry schedule or availability guarantee exists.
- Every explicit retry is a new attempt; there is no idempotency-key contract.
Use a bounded client timeout. The service's exact processing-time limit is not a public numeric contract. Preserve X-Request-Id for support and reconciliation, but treat it as opaque.
Key revocation and evaluation expiration
Dedicated keys may be revoked or disabled out of band, including at evaluator request or when an evaluation ends. Revocation produces the uniform HTTP 401 response and does not expose its reason.
Private-alpha keys do not carry an automatic expiration timestamp or cryptographic TTL. A time-bounded evaluation ends through scheduled or manual revocation at the agreed time; a stated evaluation term is not native token expiration.
Privacy and proprietary implementation
Expressions and results necessarily reach the hosted service and exist transiently while a request is processed. The durable application/accounting contract does not persist the expression, raw request body, result body, Authorization header, or plaintext API key.
Durable operational/accounting records may retain opaque request, customer, key, and usage identifiers; timestamps; outcome/status; byte counts; quota/billable units; delivery disposition; and service/profile metadata. This is not a promise of anonymity, zero transient memory, zero operating-system or network-provider logging, or a particular retention duration.
All SumWise implementation remains private and proprietary. This page and the linked machine-readable files disclose the interoperable REST contract only. Integration requires no access to SumWise implementation source.
Engine-version labeling
engine_version is an immutable process-level strict-SemVer behavior identity. Record it for reconciliation, but do not hard-code one observed value unless SumWise explicitly qualifies that dependency.
A label such as 0.1.0-dev.1+untrusted.local is a development/pre-release identity. Its build-metadata suffix describes local build provenance; it does not characterize a customer's expression or result.
Language-neutral examples
These examples make one request, use normal TLS verification, and add no automatic retry. The 30-second client timeout is an example client choice, not a service-level promise.
cURL
curl --request POST \
--max-time 30 \
--header "Authorization: Bearer ${SUMWISE_API_KEY}" \
--header "Content-Type: application/json" \
--data-binary '{"expression":"sum(12,18,25)"}' \
https://api.sumwisecalc.com/v1/evaluate
Generic Python REST call
import http.client
import json
import os
import ssl
api_key = os.environ["SUMWISE_API_KEY"]
body = json.dumps({"expression": "abs(-7/3)"}, separators=(",", ":"))
connection = http.client.HTTPSConnection(
"api.sumwisecalc.com", 443, timeout=30, context=ssl.create_default_context()
)
try:
connection.request(
"POST", "/v1/evaluate", body=body.encode("utf-8"),
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
)
response = connection.getresponse()
response_body = response.read()
print(response.status, response.getheader("X-Request-Id"))
print(json.loads(response_body))
finally:
connection.close()
Server-side JavaScript
Never put an API key in browser-delivered JavaScript.
const response = await fetch("https://api.sumwisecalc.com/v1/evaluate", {
method: "POST",
redirect: "error",
signal: AbortSignal.timeout(30_000),
headers: {
Authorization: `Bearer ${process.env.SUMWISE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ expression: "ceil(7/3)" }),
});
const requestId = response.headers.get("x-request-id");
const payload = await response.json();
console.log(response.status, requestId, payload);
C# HttpClient
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
var apiKey = Environment.GetEnvironmentVariable("SUMWISE_API_KEY")
?? throw new InvalidOperationException("SUMWISE_API_KEY is required.");
using var handler = new HttpClientHandler { AllowAutoRedirect = false };
using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(
HttpMethod.Post, "https://api.sumwisecalc.com/v1/evaluate");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
request.Content = new StringContent(
"{\"expression\":\"mean(10,20,30)\"}", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
var requestId = response.Headers.TryGetValues("X-Request-Id", out var values)
? values.SingleOrDefault() : null;
var payload = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{(int)response.StatusCode} {requestId} {payload}");
n8n HTTP Request node
- Method:
POST - URL:
https://api.sumwisecalc.com/v1/evaluate - Authentication: stored Header Auth, header
Authorization, valueBearer <api-key> - Body:
{"expression":"max(4,9/2,8)"} - Response format: JSON
- Retry on fail: disabled
- Timeout: a bounded workflow value, for example 30,000 ms
Store the key in n8n's credential store; do not hard-code it in workflow or expression data.
Machine-readable contract
The OpenAPI document covers the HTTPS operation, opaque Bearer authentication, statuses, media types, response headers, examples, and body-schema references. The JSON Schema covers the closed request, three-way success union, and deliverable problem bodies.