> For the complete documentation index, see [llms.txt](https://docs.goassay.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.goassay.ai/developers/list-your-api-advanced/map-your-api.md).

# Map your API to a tool contract

Translate a tool's inputs and outputs into the request and response your API already uses.

A tool contract describes the arguments a customer supplies and the result they receive. Its `inputSchema` and `outputSchema` define the JSON fields and types. Use a mapping when your API uses different names, nesting or request parameters.

## How it works

Assay checks the tool input against `inputSchema`, then maps it into an HTTP request. It calls your API, classifies the response, maps the returned JSON and checks the mapped result against `outputSchema`. The response mapping reads the body, not an envelope containing HTTP status and headers.

| Direction | Read from            | Write to                                                              |
| --------- | -------------------- | --------------------------------------------------------------------- |
| Request   | Tool arguments       | Method (`GET` or `POST`), appended path, query, headers and JSON body |
| Response  | Your API's JSON body | The tool's output fields                                              |

A mapping rearranges data and applies named transforms; it does not run custom code. Keep credentials in **Add headers**, outside the mapping.

## Example

Suppose the tool takes `{"city":"Hanoi"}` and promises a numeric `temperatureC`. Your API accepts a `location` query parameter and returns `{"weather":{"temp_c":"27.5"}}`.

With **Your API's address** set to `https://api.example.com`, use this request mapping:

```json
{
  "method": "GET",
  "path": "/weather",
  "query": {
    "location": { "$path": "$.city" },
    "units": { "$const": "metric" }
  }
}
```

Use this response mapping:

```json
{
  "temperatureC": {
    "$path": "$.weather.temp_c",
    "$transform": ["toNumber"]
  }
}
```

The request calls `/weather` with `location=Hanoi` and `units=metric`. The mapped result is `{"temperatureC":27.5}`. These names are illustrative: use the fields in your selected contract and actual API response.

## Save and test the mapping

1. Open your listing's **Connect & test** step. Set **Your API's address** and authentication for your endpoint.
2. Open **Advanced mapping** under **How we call your API**.
3. Edit **How a call reaches your API** and **How your answer becomes the result**. Turn on **Edit as JSON** to paste the corresponding mapping objects.
4. Enter valid tool input and click **Save and run test**.
5. Compare the generated request, raw response, mapped result and verification findings. Fix the first failing layer, then run the test again.

The tester makes a real call to your API. It uses the listing's timeout, capped at 30 seconds. Later layers marked `NOT_REACHED` have not been checked. `INCONCLUSIVE` also does not mean a pass. If no verification policy is stored, the tester uses the tool schema alone and labels that result `TOOL_SCHEMA_ONLY`.

## Check it worked

Check the mapped values as well as the green result. Try representative inputs, including an empty answer and optional fields. After changing the call or mapping, run the tester again. Publishing needs a passing test for each contract major version you serve.

## Details

| Mapping node                                                  | Behavior                                                                                                                                     |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `{"$path":"$.city"}`                                          | Reads a field from the source document. A missing path fails unless you supply a default or mark it optional.                                |
| `{"$const":"metric"}`                                         | Writes a literal value.                                                                                                                      |
| `$default`                                                    | Supplies a value when the path is absent. It does not replace explicit `null` by default.                                                    |
| `$optional: true`                                             | Omits an absent field. It does not waive a required output in the contract.                                                                  |
| `$onNull`                                                     | `PASS` by default; `DEFAULT` uses `$default`; `ERROR` rejects null.                                                                          |
| `$transform`                                                  | Applies named transforms in order, such as `toNumber` or `epochSecondsToIso`.                                                                |
| `{"$from":"$.items[*]","$item":{"title":{"$path":"$.name"}}}` | Maps each selected item; selectors inside `$item` read that item. `$onEmpty` defaults to `PASS` (`[]`); `ERROR` rejects an empty collection. |

Path templates such as `/cities/{$.cityId}` encode the selected scalar as a path segment. Query and header values must be scalars and become strings. Objects, arrays and null need a deliberate conversion before they can go there. Do not repeat an endpoint's path prefix in the mapping's appended path.

<details>

<summary>Optional: understand missing-field attribution</summary>

A response selector that resolves to nothing normally points to a mapping defect, attributed to the platform. A selector that resolves to a value of the wrong type points to bad provider data. This distinction is evidence for classification, not an automatic penalty.

An optional output you explicitly promise to provide becomes required for your listing. If it is missing or null, Assay treats it as a broken provider promise, even though the base contract calls it optional.

</details>

## Errors

| Mismatch                                              | Fix                                                                                                                    |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `TOOL_MAPPING_PATH_NOT_FOUND`                         | Compare the selector with the actual JSON nesting and spelling.                                                        |
| `TOOL_MAPPING_TYPE_MISMATCH`                          | Match the schema type; use a transform only when it preserves the meaning.                                             |
| `TOOL_MAPPING_NULL_VALUE`                             | Decide whether null is valid, should use a default, or must fail.                                                      |
| `TOOL_MAPPING_REQUIRED_FIELD_MISSING`                 | Supply the required input or output, including outputs you promised to provide.                                        |
| `TOOL_MAPPING_EMPTY_COLLECTION`                       | Check the selector and whether the contract permits an empty answer.                                                   |
| HTTP success but classification or verification fails | A successful HTTP status alone does not prove that the returned data meets the contract. Read the first failing layer. |

## Go further

* [API key or signature](/developers/list-your-api-get-started/api-key-or-signature.md).
* List your API (optional): [Map your API](https://docs.goassay.ai/list-your-api/list-a-catalogue-tool).

## Next

* [Run the verifier in production](/developers/list-your-api-advanced/run-in-production.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.goassay.ai/developers/list-your-api-advanced/map-your-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
