---
title: "Use JSON Schema with API actions and client actions"
description: "Brainfish actions can collect structured inputs from the customer before an action runs. You can define those inputs visually in the action builder, or paste a JSON Schema when you already know the form shape you need."
canonical_url: "https://help.brainfi.sh/articles/use-json-schema-with-api-actions-and-client-actions-kUYX8E377D"
md_url: "https://help.brainfi.sh/articles/use-json-schema-with-api-actions-and-client-actions-kUYX8E377D.md"
---
# Use JSON Schema with API actions and client actions

Brainfish actions can collect structured inputs from the customer before an action runs. You can define those inputs visually in the action builder, or paste a JSON Schema when you already know the form shape you need.

Use JSON Schema when you want to:

* Keep input definitions consistent across environments.
* Copy an existing schema from your app or API documentation.
* Define required fields, labels, descriptions, and select options precisely.
* Make it easier for developers to review and maintain action input contracts.

## Supported schema shape

Brainfish expects an object JSON Schema with `properties` for each input. Add field names to `required` when the customer must provide them before the action runs.

```json
{
  "type": "object",
  "properties": {
    "order_id": {
      "type": "string",
      "title": "Order ID",
      "description": "The order number shown in your confirmation email"
    },
    "reason": {
      "type": "string",
      "title": "Reason",
      "description": "Why the customer is checking this order",
      "oneOf": [
        { "const": "delivery_status", "title": "Delivery status" },
        { "const": "change_address", "title": "Change address" },
        { "const": "cancel_order", "title": "Cancel order" }
      ]
    }
  },
  "required": ["order_id"],
  "additionalProperties": false
}
```

Brainfish uses the schema to generate the customer-facing form. Common field patterns include:

* `type: "string"` for text inputs.
* `type: "number"` for numeric inputs.
* `format: "email"` for email inputs.
* `format: "date"` for date inputs.
* `oneOf` with `{ "const", "title" }` options for select inputs.

## API actions

Use an API action when Brainfish should call an HTTP endpoint on your behalf after collecting the required inputs.

Typical setup:


1. Create or edit an API action.
2. Define the inputs using the form builder or paste a JSON Schema.
3. Map the collected input values into the API request URL, headers, or body.
4. Save and test the action.

Example request body using collected inputs:

```json
{
  "orderId": "{{ order_id }}",
  "reason": "{{ reason }}"
}
```

When the customer submits the form, Brainfish validates the required inputs and sends the configured API request.

## Client actions

Use a client action when your own frontend should run the action logic. This is useful when the action must access browser-only context, customer session state, or your app's authenticated APIs.

Typical setup:


1. Create or edit a client action.
2. Define the customer inputs using the form builder or paste a JSON Schema.
3. Save the action.
4. Register a client action handler wherever the Brainfish Widget is loaded.

```javascript
Brainfish.Widgets.registerClientActionHandler('<action_key>', async (inputs) => {
  // Your custom logic here, such as calling your app's authenticated API.
  return { success: true };
});
```

Replace `<action_key>` with the action key shown in Brainfish. The `inputs` argument contains the values collected from the customer form.

Example:

```javascript
Brainfish.Widgets.registerClientActionHandler('bf_action_check_order_status', async (inputs) => {
  const response = await fetch('/api/orders/status', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      orderId: inputs.order_id,
      reason: inputs.reason
    })
  });

  if (!response.ok) {
    return {
      success: false,
      message: 'Unable to check the order status right now.'
    };
  }

  const result = await response.json();

  return {
    success: true,
    data: result
  };
});
```

## API action vs client action

Choose an API action when Brainfish can safely make the HTTP request directly using the configuration you provide.

Choose a client action when the request needs to happen inside your frontend, for example when it depends on the customer's logged-in browser session, app-specific state, or frontend-only SDKs.

## Tips

* Use clear property names like `order_id`, `email`, or `reason` because developers will use these keys in API mappings or client handlers.
* Add `title` and `description` to make the generated form easier for customers to understand.
* Keep schemas focused. Only ask for inputs that are required to run the action.
* Use `additionalProperties: false` to make the expected input contract explicit.
* Test the generated form before publishing the action.
