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

# Custom API Request: Connect External APIs to Plural

> Call any external HTTPS REST API from your flow, map response values to variables, and speak or display live data with your robot.

The Custom API Request element lets your robot or Avatar communicate with the outside world. Use it to fetch live data from a weather service, submit a form to your CRM, look up inventory, trigger a backend workflow, or exchange data with a [Plural Automation](/en/elements/plural-automation) frame. Responses are mapped to flow variables using JSONPath expressions, and those variables can be spoken aloud, shown on screen, or used to branch your flow.

## Add a Custom API Request element

Right-click on an empty area of your canvas and select **Custom API request**. Click the element once to open the configuration sidebar.

## Configure the request

### Request URL

Enter the full HTTPS endpoint URL in the **Request URL** field. HTTP is not supported — all requests must use a secure HTTPS connection.

You can embed flow variables inside the URL using `#ATTRI/variableName`:

```
https://api.example.com/products/#ATTRI/productId
```

### Request method

Click the method dropdown to select the HTTP verb:

| Method   | Typical use                           |
| -------- | ------------------------------------- |
| `GET`    | Retrieve data without a body          |
| `POST`   | Create a new resource                 |
| `PUT`    | Replace an existing resource          |
| `PATCH`  | Partially update an existing resource |
| `DELETE` | Remove a resource                     |

### Request headers

Click **Change header** to add or modify HTTP headers. Supported header types include:

* **Authorization** — authentication credentials (API key, Bearer token).
* **WWW-Authenticate** — server-initiated authentication challenges.
* **Accept-Charset** — acceptable character sets (e.g., UTF-8).
* **Content-Type** — the media type of the request body (e.g., `application/json`).
* **Cache-Control** — caching directives for the request.

### Request body (POST, PUT, PATCH)

Choose a body type from the dropdown:

<Tabs>
  <Tab title="Raw JSON">
    Send a JSON object as the body. Enter valid JSON in the editor, using `#ATTRI/variableName` to inject variable values:

    ```json theme={null}
    {
      "userId": "#ATTRI/userId",
      "query": "#ATTRI/UserQuery"
    }
    ```
  </Tab>

  <Tab title="Raw Text / HTML">
    Send plain text or HTML content as the request body.
  </Tab>

  <Tab title="Form Data">
    Send key-value pairs as `multipart/form-data` — ideal for structured data and file uploads.
  </Tab>

  <Tab title="URL Encoded">
    Send key-value pairs encoded as `application/x-www-form-urlencoded` — commonly used for simple form submissions.
  </Tab>
</Tabs>

## Save response values to variables

After a successful request, map values from the JSON response body to flow variables using JSONPath expressions.

In the sidebar, click **Add transformation rule** and fill in:

<ParamField path="JSON Path" type="string" required>
  A JSONPath expression that points to the value you want to extract. Use `$` for the root and `.property` to navigate object keys.

  **Examples:**

  * `$.temperature` — extracts the `temperature` field from the root.
  * `$.data.user.name` — navigates nested objects.
  * `$.results[0].title` — accesses the first item in an array.
</ParamField>

<ParamField path="Variable name" type="string" required>
  The Plural attribute name where the extracted value will be stored. For example: `currentTemperature`.
</ParamField>

### Use the test button

Click **Test request** at the bottom of the sidebar to send the request immediately and inspect the raw JSON response. Click on any value in the response to copy its JSONPath automatically.

## Use saved variables in speech and other elements

Once a response value is stored in a variable, reference it anywhere in your flow with `#ATTRI/variableName`:

```
The current temperature in Berlin is #ATTRI/currentTemperature degrees.
```

You can also use the variable in subsequent API call URLs, button labels, conditions, and SMS messages.

## Authentication

Plural supports the following authentication methods:

* **API key** — include the key as a custom header (for example, `X-API-Key: your_key_here`).
* **Bearer token** — add an `Authorization` header with the value `Bearer your_token_here`.

<Warning>
  OAuth and SSL certificate authentication are **not** supported. If your API requires OAuth, use a middleware proxy that accepts token-based authentication from Plural and handles the OAuth flow on your behalf.
</Warning>

## CORS workaround

If the API you are calling does not support CORS (cross-origin resource sharing), you will receive a browser-level error when calling it from an Avatar flow. To work around this:

<Note>
  Change the `Content-Type` header value from `application/json` to `text/plain`. Many APIs will still parse the body correctly, and the browser will not enforce CORS preflight for `text/plain` requests.
</Note>

This does not apply to robot frames (Pepper, NAO, Temi) where there is no browser-enforced CORS restriction.

## Requirements profile for API integration

If you are documenting or sharing integration requirements with an API provider, reference these specifications:

1. **Supported methods** — POST, PUT, PATCH for write operations; GET for read; DELETE for removal.
2. **Body types** — Raw JSON, Raw Text/HTML, Form Data, URL Encoded.
3. **CORS** — If CORS is not supported, clients must set `Content-Type: text/plain`.
4. **Transport security** — HTTPS only. HTTP requests are rejected.
5. **Authentication** — API key in header or Bearer token. OAuth and SSL certificates are not supported.

## Connect the outputs

The Custom API Request element has two outputs:

* **Success** — the request returned a 2xx HTTP status code.
* **Error** — the request failed (network error, 4xx, or 5xx response).

Always connect both outputs so your flow handles API failures gracefully.
