> ## Documentation Index
> Fetch the complete documentation index at: https://docs-test.symmetry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure, Then Calculate

> The setup-then-run workflow the STE uses, and how to send configured JSON payloads to the on-premise SDK.

Every STE calculation follows the same two-phase pattern: you **configure** all of the inputs for a paycheck, then you **calculate** and read the results. Configuration gathers the location codes, tax IDs, wages, benefits, and options that describe the payroll scenario; calculation runs the engine against that configuration and returns the withholding amounts. Nothing is computed until you have finished setting up the inputs.

## The workflow

Location and tax resolution come first — converting addresses into [location codes](/ste/core-concepts/locations-and-unique-tax-ids) and querying the STE for the applicable [Unique Tax IDs](/ste/core-concepts/locations-and-unique-tax-ids). That groundwork, and the model behind it, is covered in [How the STE Works](/ste/core-concepts/how-the-ste-works). This page picks up from there, at the configure-then-calculate phase.

<Steps>
  <Step title="Configure the calculation">
    Set up everything the engine needs for the paycheck:

    * [Wages](/ste/configuration/setting-wages) by [wage type](/ste/core-concepts/wage-types), tied to location codes
    * [Tax jurisdictions](/ste/configuration/setting-jurisdictions) (the tax IDs to compute, plus per-tax options such as exemptions, residency, and year-to-date amounts)
    * [Benefit contributions and imputed income](/ste/configuration/setting-benefits) that affect withholding
    * [Engine options](/ste/configuration/engine-options) and the [payroll run parameters](/ste/core-concepts/time-periods) (pay date, pay periods per year, pay period number)

    Because returned taxes are only *potentially* applicable, this is where you exempt any tax that doesn't apply — or simply leave it out.
  </Step>

  <Step title="Calculate and read results">
    Run the calculation. Retrieve the amount withheld for each tax, along with the [gross, subject, and taxable wage amounts](/ste/core-concepts/wages-gross-subject-and-taxable), and use those values in your system to determine the employee's net pay.
  </Step>
</Steps>

## Two ways to configure

<CardGroup cols={2}>
  <Card title="Hosted Web API">
    Configuration and calculation happen in a single request: you build a JSON payload describing the full scenario and POST it to the engine, then read the response.
  </Card>

  <Card title="On-Premise SDK">
    You can build up the configuration with the SDK's setter methods, or send the same JSON request body used by the Web API directly to your local installation.
  </Card>
</CardGroup>

## Sending JSON to the on-premise SDK

The STE Web API uses JSON objects to communicate with Symmetry's hosted servers. The same payloads can be sent to a local installation of the on-premise SDK, and you'll receive JSON responses just like those from the Web API.

The key difference is headers: payloads sent to the on-premise SDK have **no headers**. You send only the request body — beginning with the opening brace and ending with the closing brace. A Web API request includes headers like the following, which you remove for the SDK:

```
Content-type: application/json
Accept: application/json
Authorization: 1234567890qwertyuiopasdfghjklzxcvbnm

{
  "SetTaxListRequest": {
    "taxReference": [
      {
        "locationCode": "39-085-1064593",
        "payDate": "2017-06-01",
        "isResident": true,
        "schoolCode": "4309"
      }
    ]
  }
}
```

Common parameters across interfaces:

* **`jsonStringIN`** (or `jsonIN`) — the body of the request.
* **`validateJSON`** — whether the STE validates the request against the schema.
* **`schemaVersion`** — which version of the STE API you're using (`"v1"`, `"v2"`, etc.). Must use a lowercase `v`.

On a successful calculation the response type matches the request type, but the response can also be an `Error` response — your code must be able to handle that. Possible response types are: `PayCalc`, `LocationCode`, `JurisdictionData`, `SetTaxList`, `TaxIDList`, `GrossUp`, `GetSchema`, `BenefitStatus`, `AccountInfo`, and `Error` (Java and .NET also include `Unknown`).

<Tabs>
  <Tab title="C/C++">
    ```c theme={null}
    char * ste_json(const ste_handle *ste, const char *jsonStringIN, bool validateJSON, const char *schemaVersion, char *responseType)

    void ste_free_ptr(void *ptr)
    ```

    <Warning>
      The response string is the return value from `ste_json()`. Make a copy of this string, then release its memory by calling `ste_free_ptr(void *ptr)`. **Failing to release the memory will cause a memory leak.**
    </Warning>
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    public APIResponse steJSON(String jsonIN, bool validateJSON, String schemaVersion)
    ```

    The method returns an `APIResponse` object:

    ```java theme={null}
    APIResponse(APIType apiType, String responseString, ResponseType responseType) throws STEException
    ```

    * `apiType` — `APIType.JSON`
    * `responseString` — the JSON response string
    * `responseType` — one of the `ResponseType` enums (`PayCalc`, `LocationCode`, `JurisdictionData`, `SetTaxList`, `TaxIDList`, `GrossUp`, `GetSchema`, `BenefitStatus`, `AccountInfo`, `Error`, `Unknown`)
  </Tab>

  <Tab title=".NET">
    ```csharp theme={null}
    public virtual APIResponse steJSON(string jsonIN, bool validateJSON, string schemaVersion)
    ```

    The method returns an `APIResponse` object:

    ```csharp theme={null}
    APIResponse(APIType apiType, string responseString, ResponseType responseType) throws STEException
    ```

    * `apiType` — `APIType.JSON`
    * `responseString` — the JSON response string
    * `responseType` — one of the `ResponseType` enums (`PayCalc`, `LocationCode`, `JurisdictionData`, `SetTaxList`, `TaxIDList`, `GrossUp`, `GetSchema`, `BenefitStatus`, `AccountInfo`, `Error`, `Unknown`)
  </Tab>
</Tabs>
