> For the complete documentation index, see [llms.txt](https://docs.coherent.global/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coherent.global/build-spark-services/additional-mappings/call-spark-services-as-functions-xcall/cs.spark_xcall-udf-function-reference.md).

# CS.SPARK\_XCALL UDF function reference

Spark services can be set up to call other Spark services. Any Spark service can become a function that can be called from any other Spark service. This feature is known as `Xcall` and is defined as a function within an Excel workbook.

Please review [Tutorial: Define CS.SPARK\_XCALL UDF](/build-spark-services/additional-mappings/call-spark-services-as-functions-xcall/tutorial-define-cs.spark_xcall-udf.md) first if you are not familiar with `Xcall`.

## Considerations

* Although `CS.SPARK_XCALL` is very powerful, use it carefully.
  * `Xcall` has additional network and resource overhead that will increase overall response latency.
  * Instead of using multiple `CS.SPARK_XCALL` to fetch single items from the same downstream, use an `[output_template]` to retrieve all the outputs at the same time.
  * If your upstream service requires making multiple downstream calls at one time, use [Tutorial: Define CS.SPARK\_XCALL UDF](/build-spark-services/additional-mappings/call-spark-services-as-functions-xcall/tutorial-define-cs.spark_xcall-udf.md#array-xcall-for-scaling).
* `CS.SPARK_XCALL` is a [dynamic array function](https://support.microsoft.com/en-us/excel/dynamic-array-formulas-and-spilled-array-behavior) that spills results outside of a single cell.
* Although the `[output_template]` is optional, it is strongly recommended to define the `[output_template]` if you have multiple outputs or table outputs.
  * This ensures that the outputs are always returned in the same position to be referenced by the formulas in the upstream service.
  * Tables in the output template shoan arrayuld have the full dimension of the table provisioned. It may appear unusual to have large blank areas, but this ensures that the outputs can be referenced correctly by the formulas in the upstream service.
* If any `CS.SPARK_XCALL` inputs are tables of single columns, then you must add `!treat_as_table` and `<input name>` as additional parameters at the end of the function.
  * Example: `CS.SPARK_XCALL("myfolder/myservice", , , "table1column", B2:B11, "!treat_as_table" , "table1column")` where the downstream input name is `table1column` and the values are in `B2:B11`.
* You can wrap `CS.SPARK_XCALL` with an [`IF`](https://support.microsoft.com/en-us/excel/functions/if-function) function to only make the call when needed. This helps to improve performance.
  * If the `IF` function will not run `CS.SPARK_XCALL` at the time of upload, make the default output return an array that is the same size as the `[output_template]`. Upon upload, Spark uses this area to bound the size of the returned outputs. If this is set to too small of an area, the responses may be truncated.
  * You can use the [`SEQUENCE`](https://support.microsoft.com/en-us/excel/functions/sequence-function) function to populate a blank array. For example, if the `[output_template]` has the dimension of `6 rows × 4 columns`, then the conditional function could be defined as `=IF(A1=FALSE, SEQUENCE(6, 4, 0, 0), CS.SPARK_XCALL(...))`.
* Recursive `Xcall` where the same downstream service is looped back will not work. For example, in the sequence `A → B → C → B`, the last `B` will not be invoked.

## Service discovery

These forms of the `CS.SPARK_XCALL` function can be used for discovery of Spark services. These definitions do not work when compiled in [Neuron](/build-spark-services/neuron.md).

`=CS.SPARK_XCALL()`

* Discover folders you have access to.

`=CS.SPARK_XCALL({folder})`

* Discover services you have inside the folder.
* Example: `=CS.SPARK_XCALL("myfolder")`

`=CS.SPARK_XCALL({folder}/{service}[])`

* Discover service versions for the service.
* Example: `=CS.SPARK_XCALL("myfolder")`

`=CS.SPARK_XCALL("{folder}/{service}[version]")`

* View the input template for `[input_location]` of the downstream service. If `[version]` is not defined, the latest service version will be referenced. Using `[input_name_or_values]`  is preferred to using input templates.
* Example 1: `myfolder/myservice`
* Example 2: `myfolder/myservice[1]` takes the latest major version `1`.
* Example 3: `myfolder/myservice[1.2]` takes the latest minor version `1.2` .
* Example 4: `myfolder/myservice[1.2.3]`

## Function parameters

`CS.SPARK_XCALL(service, [input_location], [output_template], [input_name_or_values], [input_name_or_values])`

How parameters are used may depend on the type of `CS_SPARK_XCALL` definition. See [Tutorial: Define CS.SPARK\_XCALL UDF](/build-spark-services/additional-mappings/call-spark-services-as-functions-xcall/tutorial-define-cs.spark_xcall-udf.md) for examples of each definition.

| Downstream inputs to send                                     | Downstream outputs to receive                                                     | Recommended CS.SPARK\_XCALL definition |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------- |
| Any number of inputs and types                                | `1` single value output                                                           | `Xcall` without output template        |
| Any number of inputs and types                                | <p><code>2+</code> single value output<br>OR<br><code>1+</code> table outputs</p> | `Xcall` with output template           |
| Make multiple `Xcall` at a time with single value inputs only | `1+` single value outputs                                                         | Array `Xcall` for scaling              |

### `[service]`

Service URI expressed in `{folder}/{service}[version]` format.

* Example 1: `myfolder/myservice`
* Example 2: `myfolder/myservice[1]` takes the latest major version `1`.
* Example 3: `myfolder/myservice[1.2]` takes the latest minor version `1.3` .
* Example 4: `myfolder/myservice[1.3.2]`

### `[input_location]`

Reference to a range where the input template is defined. In [Tutorial: Define CS.SPARK\_XCALL UDF](/build-spark-services/additional-mappings/call-spark-services-as-functions-xcall/tutorial-define-cs.spark_xcall-udf.md) `[input_location]` is always left empty because the name-value pairs method of `[input_name_or_values]` is easier to use.

* The input template of a Spark service can be found using `=CS.SPARK_XCALL("{folder}/{service}[version]")`.
* Input template is defined by a range reference. Inside this range:
  * The left most column is for the input names.
  * The columns to the right define the area that contain values or references to the input values.
    * Single values need only one cell.
    * Tables should include the table headings.
* &#x20;This can be used in conjunction with the `[input_name_or_values]` name-value pairs. If an input is in both `[input_location]` and `[input_name_or_values]`, the input value in `[input_name_or_values]` takes precedence.

### `[output_template]`

This defines how outputs are written back to the dynamic spill range, including which outputs and the order in which they are returned.

| CS.SPARK\_XCALL definition                  | Description                                                                                                                                                                                                                                                                                                                                                     | Example                                                                   |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `Xcall` without output template             | <p>Spark will use its own logic to lay out how outputs returned from the downstream service are written to the upstream service.</p><p>This is not recommended.</p>                                                                                                                                                                                             |                                                                           |
| `Xcall` with a single value output template | Name or reference to the name of an output from the downstream service.                                                                                                                                                                                                                                                                                         | <p>Example 1: <code>B10</code><br>Example 2: <code>scalar\_det</code></p> |
| `Xcall` with range output template          | <p>Output template is defined by a range reference. Inside this range:</p><ul><li>The left most column is for the output names.</li><li>The columns to the right define the space where the outputs will be placed. Single values need only one cell.<br>Tables should have the table headings and the maximum size of the output response allocated.</li></ul> | Example: `C15:E15`                                                        |
| Array `Xcall` for scaling                   | Output template is defined by a range reference. This should be arranged as a `1 row × n column` range of output names.                                                                                                                                                                                                                                         | Example: `B9:D12`                                                         |

### `[input_name_or_values], [input_name_or_values]`

The name-value pairs method is used to include inputs or `request_meta` to the downstream service. The parameters should always be provided in pairs:

* Name or reference to the name of the input(s).
* Value or reference to the values of the input(s).

| CS.SPARK\_XCALL definition                                                                         | Description                                                                                                                                                                                | Example                                                                                                                                                                       |
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><code>Xcall</code> without output template<br>OR<br><code>Xcall</code> with output template</p> | <p>Name or reference to the name of the n<sup>th</sup> input to the downstream.<br><code>,</code><br>Value or reference to the values of the n<sup>th</sup> input to the downstream.</p>   | <p>Example 1: <code>"scalar",C3</code><br>Example 2: <code>B3,C3</code><br>Example 3: <code>"matrix",C5:D7</code><br>Example 4: <code>B5,C5:D7</code></p>                     |
| Array `Xcall` for scaling                                                                          | <p>Name or reference to the name of the n<sup>th</sup> input to the downstream.<br><code>,</code><br>Value or reference to the values of the n<sup>th</sup> input from the downstream.</p> | <p>Example 1: <code>C3,C4:C6</code> single column<br>Example 2: <code>C3,C4:C6,D3,D4:D6</code> separate columns<br>Example 3: <code>C3:D3,C4:D6</code> contiguous columns</p> |

## Request meta

Certain [Execute API (v3)](/spark-apis/execute-api/execute-api-v3.md#request_meta) can be used with `Xcall` using additional `[input_name_or_values], [input_name_or_values]`.

### `#service_category`

Use with `[input_name_or_values]`  to define the [Sub functions with subservices](/build-spark-services/additional-mappings/sub-functions-with-subservices.md) to run.

* Example 1: `"#service_category", "Subservice1"`
* Example 2: `"#service_category", "Subservice1,Subservice2"`
* Example 3: `"#service_category", C4:C6` where `C4:C6` is a list of subservices.

## Trace `Xcall` iterations

The downstream `Xcall` calls can be traced using the [Execute API (v3)](/spark-apis/execute-api/execute-api-v3.md#request_meta) `debug_xcall`.

* Open the [API Tester](/navigation/api-tester.md) for the service.
* In **API request (inputs)**, select **Raw view**.
* In the `request_meta`, add a comma `,` at the end of the last entry and then add `"debug_xcall": true`.
* **Submit** the API call.
* In In **API response (outputs)**, select **Raw view**. Under `response_data`, `outputs`, `additional_outputs` contains an  `xcall_log` array with a list of downstream `Xcall`s made and the associated `call_id`.

<details>

<summary>Sample <code>xcall_log</code></summary>

```json
{
    "response_data": {
        "outputs": {
            ...,
            "additional_outputs": {
                "xcall_log": {
                    "trace_id": "d22ac2e5-0c81-4ffd-8310-8d0332b6666b",
                    "total_xcall_count": 1,
                    "total_xcall_process_time": 4,
                    "xcalls": [
                        {
                            "service": "xcalls/ab_operations",
                            "xcall_id": [
                                "01a06273-78c7-74df-8485-da2f7db0feed"
                            ],
                            "xcall_self": false,
                            "xcall_count": 1,
                            "xcall_process_time": 4,
                            "xcall_process_time_breakdown": [
                                4
                            ],
                            "xcalls": []
                        }
                    ]
                }
            }
        },
        "warnings": null,
        "errors": null
    },
    "response_meta": {
        ...
    }
}
```

</details>
