> For the complete documentation index, see [llms.txt](https://docs.baas.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.baas.sh/baas-console/automations/actions/api.md).

# API

Send an HTTP request to any HTTPS URL and hand the response to the next step.

The API action sends an HTTP request to the URL you choose. In this guide, the weekly rewards automation from the [Cron](/baas-console/automations/triggers/cron.md) page reports each distribution to your backend: a [transaction action](/baas-console/automations/actions/transaction.md) sends the tokens, then an API action POSTs the result.

## Set up the request

{% stepper %}
{% step %}

### Pick the API type

[Add a step](/baas-console/automations/actions.md) to the pipeline and pick **API**.
{% endstep %}

{% step %}

### Set the URL and method

**URL** takes the endpoint to call, as a literal or a template, and it starts with `https://`. **HTTP method** offers **GET**, **POST**, **PUT**, **PATCH**, and **DELETE**. In our example, the backend expects a POST on `https://api.example.com/rewards`.

A variable missing from the URL fails the run. Write `{{trigger.body.q?}}` for a value that may legitimately be absent, such as an optional query parameter — it then renders as empty text.
{% endstep %}

{% step %}

### Write the body

**Body** holds the JSON to send, and it appears for POST, PUT, and PATCH. Write a dynamic value as `{{...}}` where the value goes, not inside quotes. In our example, the body reports the transaction confirmed in the previous step:

```json
{
  "event": "weekly-rewards",
  "transactionId": {{context.previous.transactionId}}
}
```

The body is always JSON, and each `{{...}}` value is escaped for you, so a quote or a newline in the data cannot break the JSON. An optional value that is missing, written `{{trigger.body.note?}}`, lands as `null`.

Leave **Body** empty and the action sends no body. To send the trigger's data, put `{{trigger}}` there.
{% endstep %}

{% step %}

### Save

Click **Save**. The request now goes out on every run.
{% endstep %}
{% endstepper %}

## Headers and timeout

* **Headers** is an optional JSON object whose values accept templates and must not render empty. Use it for anything your endpoint expects, like an API key header. Without a `Content-Type`, a body is sent as `application/json`.
* **Timeout (s)** caps the wait for a response, from 1 to 120 seconds. It defaults to the project-wide setting, 15 seconds unless you [changed it](/baas-console/action-plugins.md#api-defaults).

## Automatic retries

Outside batch mode, transient failures are retried automatically for GET, PUT, and DELETE. For POST and PATCH, retrying is opt-in: the **Advanced** section offers a **Safe to retry transient failures** toggle. Turn it on only when your endpoint handles the same request twice without side effects; in our example it is safe, because the backend keys each report on its `transactionId`. Retry attempts show up in the [run's logs](/baas-console/automations/runs-and-logs.md).

## What the next step receives

| Field          | Contents             |
| -------------- | -------------------- |
| `status`       | The HTTP status code |
| `responseData` | The response body    |

The next action reads them as `{{context.previous.status}}` and `{{context.previous.responseData}}`.

{% hint style="info" %}
**A non-2xx response fails the action.** The run stops there.
{% endhint %}

## Next

* [Transaction](/baas-console/automations/actions/transaction.md): the step this example reports on.
* [Action Plugins](/baas-console/action-plugins.md#api-defaults): project-wide request defaults.
* [Actions](/baas-console/automations/actions.md): back to the section overview.
