Skip to content

Calculation

The calculation endpoints run the tool’s live version on the server. The two endpoints behave the same; one addresses by key, the other by toolId (key is recommended for integrations):

POST /v1/public/tools/by-key/{key}/calculate
POST /v1/public/tools/{toolId}/calculate
{
"inputs": { "amount": "1000", "mode": "exclusive", "vatRateOption": "standard" },
"asOf": "2026-01-15",
"version": 1
}
Field Required Description
inputs yes Field name → value. The keys are the names in inputSchema.fields.
asOf no The date the rates are in force, YYYY-MM-DD. Defaults to today (Europe/Istanbul).
version no The versionNumber you read from the definition. 409 if it differs from the live version.

The request body can be at most 16 KB; unknown top-level fields are rejected.

  • Decimals and dates are strings, enum values are strings, booleans are JSON true/false.
  • A JSON number (1000) is rejected: 422 VALIDATION_ERROR, with the relevant path in details.issues[].
  • If required: false fields are not sent, default is used.
  • A field that is not in the definition → details.fields[].reason = "UNKNOWN_INPUT".
  • Range and scale checks: OUT_OF_RANGE, SCALE_EXCEEDED; a missing required field is MISSING_INPUT, a null value is NULL_INPUT.
{
"data": {
"result": { "net": "1000.00", "vat": "200.00", "gross": "1200.00" },
"breakdown": [
{ "key": "net", "value": "1000.00", "format": "money", "scale": 2, "currency": "TRY" },
{ "key": "vat", "value": "200.00", "format": "money", "scale": 2, "currency": "TRY" },
{ "key": "gross", "value": "1200.00", "format": "money", "scale": 2, "currency": "TRY" }
]
},
"meta": {
"toolId": "8410ffe8-825a-41a1-9488-078f3a7c7f42",
"toolVersion": 1,
"asOf": "2026-10-11",
"engineVersion": "1.2.0",
"dslVersion": 1,
"rates": [
{
"binding": "vatRate",
"key": "tr.vat.standard",
"rateId": "31fb806c-…",
"valueId": "65a8771b-…",
"version": 1,
"value": "20",
"effectiveFrom": "2023-07-10",
"effectiveTo": null
}
]
}
}
  • result: result key → string value. Read it directly by key in your code (data.result.gross).
  • breakdown: an ordered list of the same results with format information (format, scale, currency, unit). Use this if you are drawing a results table; the order is the one the tool defines.
format Meaning Display suggestion
money Money (currency) Intl.NumberFormat('tr-TR', { style: 'currency', currency })
percent Percentage value ("20" = 20%) 20 %
number Number As many decimals as scale
date Date YYYY-MM-DD Local date format

To format the string value without converting it to floating point, use a decimal library (decimal.js, Python Decimal, .NET decimal); or display the string as it is.

  • toolVersion, asOf: the tool version and the rate date used in the calculation.
  • rates[]: every rate used: key, value, version, effectiveFrom/To. Store this field to document what the calculation is based on.
  • engineVersion, dslVersion: calculation engine versions (informational).

With asOf, calculate with the rates in force on that date (e.g. a past VAT rate):

Terminal window
curl -X POST "https://api.mirac-ozdemir.com/v1/public/tools/by-key/kdv/calculate" \
-H "Content-Type: application/json" \
-d '{"asOf":"2023-01-15","inputs":{"amount":"1000","mode":"exclusive","vatRateOption":"standard"}}'

If no rate was in force on that date, 422 RATE_UNAVAILABLE is returned (details.rates, details.asOf). For example, a very old date for which a rate is not defined gives this error.

If you cached the definition and generated your form from it, send version in the calculation. If the tool has been updated in the meantime, the calculation is not performed:

{ "error": { "code": "CONFLICT", "message": "…", "details": { "reason": "VERSION_OUTDATED", "currentVersion": 2 } }, "requestId": "…" }

In this case, fetch the definition again (getToolByKey), update your form and repeat the request. If you always want fresh data, you can omit version and calculate with the live version every time.

  • Calculation endpoints are limited to 60 requests per minute per IP; the limit of the two endpoints is shared.
  • Calculation responses come with no-store; they must not be cached.
  • A tool under maintenance returns 503 MAINTENANCE.

All error codes and handling suggestions: Errors.