> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt

## Resource: Add Self-Managed App Tool Extensions with REST

## Article: Add Self-Managed App Tool Extensions with REST

## Article Link: https://dev.wix.com/docs/build-apps/develop-your-app/develop-a-self-managed-app/supported-extensions/backend-extensions/app-tools/add-self-managed-app-tool-extensions-with-rest.md

## Article Content:

# Add Self-Managed App Tool Extensions with REST

Add an [App Tools extension](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/backend-extensions/app-tools/about-app-tools-extensions.md) to your app to expose your app's capabilities to [Aria](https://dev.wix.com/docs/overview/ai-the-wix-platform/about-aria.md), Wix's AI assistant. After a Wix user installs your app, Aria can discover and invoke the tools your app declares, allowing Wix users to interact and perform actions with your app through natural language.

This article covers the REST implementation. If you prefer a different approach, see:
- [Add Self-Managed App Tool Extensions with the SDK](https://dev.wix.com/docs/build-apps/develop-your-app/develop-a-self-managed-app/supported-extensions/backend-extensions/app-tools/add-self-managed-app-tool-extensions-with-the-sdk.md)
- [Add App Tools Extensions with the CLI](https://dev.wix.com/docs/build-apps/develop-your-app/develop-an-app-with-the-cli/supported-extensions/backend/schema-plugins/add-app-tools-extensions-with-the-wix-cli.md)

Follow these steps to implement a self-managed app tools extension with REST:

## Step 1 | Add an App Tools extension

Declare the tools your app exposes to Aria in the [app dashboard](https://manage.wix.com/account/custom-apps).

To add an App Tools extension to your app:

1. Select an app from the [Custom Apps page](https://manage.wix.com/account/custom-apps) in your Wix Studio workspace.

1. On the **Extensions** page, click **+ Create Extension**.

   ![Create Extension button on the Extensions page](https://wixmp-833713b177cebf373f611808.wixmp.com/images/72e71b0414df528b52e1b149f8b15114.png)

1. Search for **App Tools** and click **+ Create**.

1. In the JSON editor, configure your tools by referencing the **Documentation** panel on the right side of the page.

   ![App Tools extension JSON editor with the Documentation section open](https://wixmp-833713b177cebf373f611808.wixmp.com/images/e1bedd15e60134b733bb643b7ef7ca55.png)

   The following example configures a package tracking tool:

   ```json
   {
     "tools": [
       {
         "methodName": "getPackageTracking",
         "description": "Fetches the current tracking status of a package by its tracking number. Returns status, location, and estimated delivery date. Use when the Wix user wants to know where their package is or when it will arrive.",
         "requestSchema": {
           "type": "object",
           "required": ["trackingNumber"],
           "properties": {
             "trackingNumber": {
               "type": "string",
               "description": "The carrier tracking number for the package, for example '1Z999AA10123456784'."
             }
           }
         },
         "responseSchema": {
           "type": "object",
           "properties": {
             "trackingNumber": { "type": "string" },
             "status": { "type": "string" },
             "location": { "type": "string" },
             "estimatedDelivery": { "type": "string" }
           }
         },
         "activated": true
       }
     ]
   }
   ```

   > **Note:** Write each tool `description` comprehensively. Aria compares the Wix user's request against each tool's description to decide which tool to call. A vague description reduces the chance that Aria selects the right tool at the right time. Learn more about [effective tool descriptions](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/backend-extensions/app-tools/about-app-tools-extensions.md#effective-tools).

1. Click **Save**.

## Step 2 | Add a Tools Provider service plugin

Add a [Tools Provider service plugin](https://dev.wix.com/docs/api-reference/app-management/app-tools/tools-provider-v1/introduction.md) to your app. When Aria invokes one of your tools, Wix sends a `POST` request to `{baseUri}/v1/run-tool` on your server. In this plugin, you set `baseUri` to the URL where your app is hosted so Wix knows where to send that request.

To [add a Tools Provider service plugin](https://dev.wix.com/docs/build-apps/develop-your-app/develop-a-self-managed-app/supported-extensions/backend-extensions/service-plugins/add-self-managed-service-plugin-extensions-with-rest.md):

1. On the **Extensions** page, click **+ Create Extension** again.

1. Search for **Tools Provider Config** and click **+ Create**.

1. In the JSON editor, set `baseUri` to the base URL where you host your app. Reference the **Documentation** panel for the full schema.

   ```json
   {
     "baseUri": {
       "baseUri": "https://<YOUR_APP_URL>"
     }
   }
   ```

   ![Tools Provider Config JSON editor with the Documentation section open](https://wixmp-833713b177cebf373f611808.wixmp.com/images/0e60fdf754290c4fe7341f393f17b9f3.png)

1. Click **Save**.

## Step 3 | Retrieve your app's credentials

Retrieve the credentials your endpoint uses to validate incoming JWTs and authenticate Wix API calls.

To validate incoming JWT requests and call Wix APIs, retrieve the following credentials from your app's dashboard:

- **App ID**: Required. Used to verify the `aud` field in incoming JWTs.
- **Public Key**: Required. Used to verify the JWT signature.
- **App Secret Key**: Only required if your [endpoint](#step-4--implement-the-run-tool-endpoint) calls Wix APIs.
- **Instance ID**: Only required if your [endpoint](#step-4--implement-the-run-tool-endpoint) calls Wix APIs. Identifies the [app instance](https://dev.wix.com/docs/build-apps/develop-your-app/auth/app-instances/about-app-instances.md) on the site that triggered the tool.

To retrieve your credentials:

1. In your [app dashboard](https://manage.wix.com/account/custom-apps), click the **More Actions** icon in the top right.
1. Select **View ID & Keys**.
1. Click **Show** and copy the **App ID** and **Public Key**. If your endpoint calls Wix APIs, also copy the **App Secret Key**.

There are several ways to retrieve an [app's instance ID](https://dev.wix.com/docs/build-apps/develop-your-app/auth/app-instances/about-app-instances.md). Learn more about [identifying the app instance in backend environments](https://dev.wix.com/docs/build-apps/develop-your-app/auth/app-instances/identify-the-app-instance-in-backend-environments.md).

## Step 4 | Implement the Run Tool endpoint

Create an HTTP endpoint at `{baseUri}/v1/run-tool` that Wix calls when Aria invokes one of your app's tools. Your endpoint must:

1. Validate the incoming JWT.
2. Extract `methodName` and `payload` from the [request envelope](#request-envelope).
3. Run your logic for the specified `methodName`.
4. Return your tool output wrapped inside a `response` object. The fields should match the `responseSchema` you configured in Step 1.

### Request envelope

Wix wraps each request your endpoint receives in a signed envelope with metadata.

The request body is a [JSON Web Token (JWT)](https://jwt.io/introduction/). After you verify and decode the JWT, the decoded token has the following structure:

```json
{
  "data": {
    "request": {
      "methodName": "<tool-method-name>",
      "payload": {}
    },
    "metadata": {
      "requestId": "<request-id>",
      "instanceId": "<site-installation-id>",
      "appExtensionId": "<app-tools-extension-id>",
      "functionName": "RunTool",
      "appExtensionType": "TOOLS_PROVIDER_CONFIG",
      "identity": {
        "identityType": "<identity-type>",
        "anonymousVisitorId": "<id>",
        "memberId": "<id>",
        "wixUserId": "<id>",
        "appId": "<id>"
      }
    }
  },
  "aud": "<your-app-id>",
  "iss": "wix.com",
  "iat": <unix-timestamp>,
  "exp": <unix-timestamp>
}
```

The `data.request` fields are:

- `methodName`: The name of the tool Aria is invoking. Matches a `methodName` you declared in your App Tools extension.
- `payload`: The input the tool receives, matching the `requestSchema` you configured in [Step 1](#step-1--add-an-app-tools-extension).

The `data.metadata` fields are:

- `requestId`: Unique identifier for the request. Log this to help with future debugging and to correlate with Wix logs.
- `instanceId`: The site's installation ID. Use this to identify which site triggered the call, and to [make outbound Wix API calls](#call-wix-apis-from-your-endpoint) on behalf of that site.
- `appExtensionId`: The ID of the App Tools extension Wix invoked.
- `functionName`: Always `"RunTool"` for App Tools requests.
- `appExtensionType`: Always `"TOOLS_PROVIDER_CONFIG"` for App Tools requests.
- `identity`: Describes the entity that triggered this request, with the following structure:
  - `identityType`: Type of identity that triggered the request. See [About Identities](https://dev.wix.com/docs/overview/auth-permissions/identities.md).
  - `anonymousVisitorId`: ID of the anonymous site visitor, when present.
  - `memberId`: ID of the site member, when present.
  - `wixUserId`: ID of a Wix user, when present.
  - `appId`: ID of an app, when present.

The top-level JWT fields are:

- `aud`: Your app's ID. Verify this value matches your App ID to confirm Wix issued the token for your app.
- `iss`: The token issuer. Always `"wix.com"`. Verify this value to confirm the token came from Wix.
- `iat`: Unix timestamp of when Wix created the token. Verify this timestamp is before the current time on your server.
- `exp`: Unix timestamp of when the token expires. Verify this timestamp is after the current time on your server.

### Validate request signatures

Verify the JWT to protect against malicious requests impersonating Wix:

- Verify the JWT signature using the public key from [your app's credentials](#step-3--retrieve-your-apps-credentials).
- Verify that `aud` matches your App ID.
- Verify that `iss` is `wix.com`.
- Verify that `iat` is before the current time on your server.
- Verify that `exp` is after the current time on your server.

We recommend that you use a standard library to parse and validate the JWT. There are libraries available for all popular languages. See the [list of JWT libraries](https://jwt.io/libraries).

The following example implements this using [Express](https://expressjs.com/) and the [`jsonwebtoken`](https://www.npmjs.com/package/jsonwebtoken) library: 

```js
import express from 'express';
import jwt from 'jsonwebtoken';

const app = express();

const APP_ID = process.env.APP_ID;
const PUBLIC_KEY = process.env.PUBLIC_KEY;

//Read the body as a string, not JSON.
app.use(express.text({ type: '*/*' }));

app.post('/v1/run-tool', async (req, res) => {
  try {
    // 1. Validate the JWT using your app's public key
    const decoded = jwt.verify(req.body, PUBLIC_KEY);

    // 2. Verify JWT fields
    if (decoded.aud !== APP_ID) throw new Error('Invalid audience');
    if (decoded.iss !== 'wix.com') throw new Error('Invalid issuer');
    if (decoded.iat > Math.floor(Date.now() / 1000)) throw new Error('Token issued in the future');

    // 3. Extract the tool method and request schema
    const { methodName, payload } = decoded.data.request;

    // 4. Route on methodName and return your response
    switch (methodName) {
      case 'getPackageTracking': {
        const trackingNumber = payload?.trackingNumber;
        if (!trackingNumber) {
          throw new Error('trackingNumber is required');
        }

        // Replace with your real tracking API call
        const shipment = await getShipmentByTrackingNumber(trackingNumber);

        return res.json({
          response: {
            trackingNumber,
            status: shipment.status,
            location: shipment.location,
            estimatedDelivery: shipment.estimatedDelivery,
          },
        });
      }
      // Handle other tools here...
      default:
        throw new Error(`Unknown tool: ${methodName}`);
    }
  } catch (err) {
    console.error('Tool call failed:', err);
    res.status(500).json({ error: err.message });
  }
});

app.listen(3000);
```

> **Notes:**
>
> - When verifying the JWT, read the body as a string. Common frameworks parse JSON bodies by default, which can cause errors when verifying the JWT.
> - Wix doesn't validate `payload` against your `requestSchema` before calling your endpoint. Handle missing or unexpected fields in your implementation.
> - If your implementation returns an error or times out, Aria continues the conversation without the tool result.


## Call Wix APIs from your endpoint

If your Run Tool logic needs to read or write site data with Wix REST APIs, authenticate as an [app instance](https://dev.wix.com/docs/build-apps/develop-your-app/auth/app-instances/about-app-instances.md) using [OAuth](https://dev.wix.com/docs/build-apps/develop-your-app/auth/authenticate-using-oauth.md). Each call needs an access token scoped to the site that triggered the tool.

For tool calls, the inbound JWT already carries the site's `instanceId` in `metadata.instanceId`, so you don't need to look it up. Pass that value, along with your App ID and App Secret Key, to [Create Access Token](https://dev.wix.com/docs/api-reference/app-management/oauth-2/create-access-token.md):

```bash
curl -X POST 'https://www.wixapis.com/oauth2/token' \
  -H 'Content-Type: application/json' \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "<YOUR_APP_ID>",
    "client_secret": "<YOUR_APP_SECRET_KEY>",
    "instance_id": "<INSTANCE_ID_FROM_JWT>"
  }'
```

Include the returned `access_token` as the `Authorization` header in your Wix API calls.

For the full flow, including how apps get `instanceId` outside of tool calls, see [Authenticate Using OAuth](https://dev.wix.com/docs/build-apps/develop-your-app/auth/authenticate-using-oauth.md).

## See also

- [About Aria](https://dev.wix.com/docs/overview/ai-the-wix-platform/about-aria.md)
- [About App Tools extensions](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/backend-extensions/app-tools/about-app-tools-extensions.md)
- [Add Self-Managed App Tool Extensions with the SDK](https://dev.wix.com/docs/build-apps/develop-your-app/develop-a-self-managed-app/supported-extensions/backend-extensions/app-tools/add-self-managed-app-tool-extensions-with-the-sdk.md)