Call a service over the API

Updated 2026-11-13

The address of a published service, how to call it with GET or POST, what a first call looks like, and the short domain. For the answer in detail see The API response.

The address

Every published service has one address:

https://spreadapi.io/api/v1/services/{serviceId}/execute

{serviceId} is the ID of your service. Copy it from the service list (three dots, Copy ID or Copy Endpoint) or take the full address from API → Test on the service page.

The service must be published. A draft cannot be called; see Publish, republish and unpublish.

A first call

The fastest way is the app itself: open the service, go to API → Test, enter values and click Run Test. See The API tester.

From a terminal, with a service that has the inputs amount and rate:

curl "https://spreadapi.io/api/v1/services/{serviceId}/execute?amount=20000&rate=0.05"

The answer:

{
  "service": { "id": "{serviceId}", "name": "Loan", "description": null },
  "inputs": [
    { "name": "amount", "title": "Amount", "value": 20000 },
    { "name": "rate", "title": "Rate", "value": 0.05 }
  ],
  "outputs": [
    { "name": "interest", "title": "Interest", "value": 1000 }
  ],
  "metadata": { "executionTime": 12, "totalTime": 15, "timestamp": "2026-11-13T09:00:00.000Z", "version": "v1" }
}

GET: inputs in the address

Put each input into the address as name=value. GET fits Excel, Google Sheets, a browser address bar and simple tools.

GET https://spreadapi.io/api/v1/services/{serviceId}/execute?amount=20000&rate=0.05

On GET, true and false are read as yes/no values and anything that looks like a number is read as a number. To send a text exactly as written, for example a code with leading zeros, use POST.

POST: inputs as JSON

Send a JSON body with an inputs object. POST is the recommended way for code.

curl -X POST "https://spreadapi.io/api/v1/services/{serviceId}/execute" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"amount": 20000, "rate": 0.05}}'

GET and POST return the same answer.

Rules for inputs

  • Use the name of an input, not its title. Names are not case-sensitive: Amount and amount are the same.
  • Required inputs must be sent. An optional input you leave out takes its default, or the value the workbook holds.
  • Names the service does not know are ignored.
  • Send percentages as decimals: 0.05 for 5%. See Percentages and formats.
  • Types and accepted spellings are in Data types; rules such as minimum, maximum and allowed values are in Input validation.

Token

A public service needs nothing more. A token-protected service needs a token with every call: as the header Authorization: Bearer <token>, or as ?token=<token> on GET. See Tokens and access.

The short domain

The same service also answers at a shorter address:

https://spreadapi.run/{serviceId}

It behaves exactly like the long address, for GET and for POST:

https://spreadapi.run/{serviceId}?amount=20000&rate=0.05

It is handy in spreadsheet formulas and wherever a long address is in the way. In API → Test you switch between the two under Domain. Everything else, such as batch calls and the OpenAPI file, lives under spreadapi.io.

Limits

  • At most 1,000 calls per minute per service, all callers together.
  • The calls per month that the plan of the service's account includes. See Call limits.
  • A call has up to 30 seconds to answer.

When a call fails

A failed call answers with JSON and an HTTP status. The text in error says what went wrong.

StatusTypical errorWhat to do
400Missing required parameters, Parameter validation failedFix the inputs; see Input errors
400Authentication required. ..., Invalid token, Token expiredSend a valid token; see Token errors
404Not foundCheck the ID and that the service is published; see Not found and unpublished
429RATE_LIMIT_EXCEEDED, Monthly call limit reachedWait or upgrade; see Limit errors
500Internal server errorTry again; contact support if it stays

Token problems answer with 400, not 401. Check the text in error, not only the status. The full list is in the Error reference.

For developers and agents

ItemValue
Addresshttps://spreadapi.io/api/v1/services/{serviceId}/execute
Short addresshttps://spreadapi.run/{serviceId}
MethodsGET, POST, OPTIONS
GET inputsQuery parameters, one per input name
POST body{"inputs": {"name": value, ...}} with Content-Type: application/json
TokenAuthorization: Bearer <token>, or ?token=<token> on GET
SuccessHTTP 200, JSON with service, inputs, outputs, metadata

Optional parameters:

ParameterWhereEffect
_formatGET queryjson (default), csv or plain
_pretty=trueGET queryIndented JSON
flatten=trueQueryAdds result, the outputs as one object keyed by name
nocdn=trueGET query, or "nocdn": true in the POST bodyAccepted, but no longer needed: answers are not stored by browsers or networks
nocache=trueGET query, or "nocache": true in the POST bodySkips the stored result and calculates again

On GET, query parameters whose name starts with _ and the names token, nocdn and nocache are not treated as inputs.

A POST body without an inputs object answers 400 with error: "INVALID_REQUEST" and the message Request body must contain "inputs" object. A service without inputs is called with {"inputs": {}}.

A failed calculation answers 400 with error, message, serviceId, the inputs you sent and details. A call over the per-minute limit answers 429 with the headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and Retry-After.

FAQ

What is the address of my API?

It is https://spreadapi.io/api/v1/services/{serviceId}/execute with your service ID. In the service list, the three dots and Copy Endpoint copy it.

Should I use GET or POST?

Both return the same answer. GET with inputs in the address fits spreadsheets and quick tests; POST with a JSON body is the recommended way for code.

How do I send the inputs with POST?

Send Content-Type: application/json and a body of the form {"inputs": {"amount": 20000, "rate": 0.05}}. The keys are the input names of your service.

Do input names have to match upper and lower case?

No. Input names are not case-sensitive. Use the name of the input, not its title.

What is spreadapi.run?

It is the short domain for calls: https://spreadapi.run/{serviceId} is the same endpoint as the long execute address. It accepts the same inputs, tokens and methods.

Why do I get 404 when I call my service?

The ID is wrong or the service is not published. A draft cannot be called; publish it first.

How many calls can I make?

At most 1,000 calls per minute per service, and the calls per month of the plan. The numbers per plan are in Call limits.

How do I send 5 percent?

Send the decimal 0.05. Details are in Percentages and formats.

As an agent, how do I find out which inputs a service expects?

Read the OpenAPI file at https://spreadapi.io/api/v1/services/{serviceId}/openapi, or open the discovery address of the service. See OpenAPI and interactive docs and The discovery address.

What happens to an optional input I leave out?

It takes its default value. Without a default, the calculation uses the value the published workbook holds in that cell.

My text value loses its leading zeros on GET. Why?

On GET, a value that looks like a number is read as a number. Send the value with POST as a JSON string, for example "zip": "01234".