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

# Call your system

> Sends a fixed request to your system and, if you want, lets an AI employee continue the conversation with the response

> [!NOTE]
>
> **Endpoint** · `POST /conversation/actions`

`send_json` **sends a request to your system** —your ERP, your CRM, your backend— with content
you write, without a model drafting it. It's the same "Call your system" action the
business team configures in an action set from the panel; here it runs on its own, inside an
action group.

If you want, an AI employee **reads what your system answers** and keeps the conversation going
with the customer. For example: register the order and have the employee confirm to the
customer the number your system returned.

How it differs from a JSON-type AI employee:

* The JSON employee **drafts** the body with a model from the conversation, and marks it with
  `is_test: true` when it runs in the Tester.
* `send_json` **always sends the body you wrote**, byte for byte. The dispatch doesn't go through a
  model or consume tokens (the continuation, if you configure one, does), and it carries no test
  marker.

**Fields**

* `url` — your system's URL, `http://` or `https://` (required, up to 2,000 characters). No username
  or password in the URL: authentication goes in `headers`.
* `method` — `GET`, `POST`, `PUT` or `PATCH`. `POST` if omitted.
* `headers` — request headers; for example, your system's authentication. Names allow letters,
  digits and hyphens, and `Host`, `Content-Length`, `Transfer-Encoding`, `Connection`, `Keep-Alive`,
  `Upgrade` and `Expect` aren't allowed; each value must be Latin-1 (no ASCII control characters
  except tab): otherwise the request is rejected with `400 INVALID_REQUEST`. Up to 50 headers, with
  names of up to 256 characters and values of up to 8,192; together, names and values add up to at
  most 16,384.
* `query_params` — parameters added to the query string of `url`. One with the same name as a parameter in `url` replaces its first occurrence, in place, and the repeated ones are dropped; the other pairs are sent as is, without being re-encoded (with `query_params`, empty segments, like `&&` or a trailing `&`, are omitted). Up to 50 parameters, with the same name and value limits as `headers`, and the URL that gets sent —encoded, with its parameters, and with the path as the request encodes it— can't exceed 8,192 characters: a path with `ñ` or accents counts more than it shows. Past any limit, the request is rejected with `400 INVALID_REQUEST`.
* `body` — the body, as **JSON text** (up to 10,000 characters). Not allowed with `GET`.
* `wrap_key` — wraps the body under that key (up to 100 characters): with `"data"`, your system receives
  `{"data":<body>}`. Requires `body`.
* `response_processor` — `{ ai_employee, instructions }`: the AI employee that reads the response
  and, optionally, what to do with it (up to 500 characters).

```jsonc theme={null}
{
  "type": "send_json",
  "url": "https://erp.example.com/api/orders",
  "headers": { "Authorization": "Bearer <your system token>" },
  "body": "{\"sku\":\"A-100\",\"qty\":2,\"price\":150.50}",
  "response_processor": {
    "ai_employee": { "name": "Asistente de Ventas" },
    "instructions": "Confirm to the customer the order number the system returns."
  }
}
```

`send_json` doesn't trigger the AI, but it **counts toward the limit of 3 AI-triggering actions**
per group, with or without `response_processor`: its response can continue the conversation. In a
list, this object goes in the `actions` array of a `POST /conversation/actions` — see [Assembling
an action list](https://docs.1to1ai.com/en/action-groups/overview.md#assembling-an-action-list).

## The body is text, not an object

`body` is a **string** with JSON inside. That's how it goes out **byte for byte**: your system
receives exactly that text, with keys in your order and numbers as you wrote them —`150.50`
doesn't become `150.5`, and an integer longer than 16 digits doesn't lose precision—. With `wrap_key`, that same text goes untouched inside the wrapper: your system receives `{"<wrap_key>":<body>}`. If it isn't
valid JSON, the request is rejected with `400 INVALID_REQUEST` and no action in the group runs.

It's **fixed**: it carries no variables or conversation data, and the request carries no platform
headers either. If your system needs to know which conversation it's about, include that yourself
in the `body` or in `query_params`.

With a body, the request carries `Content-Type: application/json`; to replace it, pass it in
`headers` under that same name. With `GET` there's no body: the data goes in the URL or in
`query_params`.

## Your system's response doesn't fail the action

Your system answering with an error, answering late or not answering at all is **not** a
`send_json` failure: the action counts as successful, doesn't trigger `stop_on_error` and doesn't
escalate the conversation. The action only fails because of something on our side, or if
`response_processor` doesn't resolve (see below). In the panel's Activity log it shows as successful,
with a note that your system answered with an error or didn't answer, or that we didn't call it because
its URL is blocked or couldn't be found.

What's worth knowing about the delivery:

* **Your system has 30 seconds to respond.** If it doesn't respond in time, or there's a network
  error, the request **is retried once, identical**: if your system processed it but was slow to
  answer, it receives it twice. If the request creates something —an order, a charge—, include
  your own identifier in the `body` and deduplicate by it.
* **Resending the group sends it again.** `POST /conversation/actions` doesn't deduplicate: if you
  retry a group with `send_json`, your system receives the request again. The same advice applies.
* **An error response is not retried**, and a redirect is not followed.
* **The URL must resolve to a public address.** A private or local IP is blocked and the request
  isn't sent.

> [!WARNING]
>
> **Tests from the Tester reach your system as real ones.** `send_json` also dispatches from the
> Tester —the panel's, or this API on a test conversation—, because without your system's real
> response there would be nothing for the AI employee to read.
>
> Unlike the JSON-type AI employee, **the request carries no test marker**: it goes out identical to
> a production one. If you don't want a test to touch your system, point the action at a test URL
> while you test.

## Continue the conversation with the response

With `response_processor`, whatever your system answers can be read by an AI employee to keep
writing to the customer. The same rules apply as for the JSON-type AI employee's response,
described in [What your endpoint answers can continue the
conversation](https://docs.1to1ai.com/en/webhooks.md#what-your-endpoint-answers-can-continue-the-conversation):

* **The employee must be operational and active.** If the name doesn't resolve to one, the action
  fails with `AI_EMPLOYEE_NOT_FOUND` —or `AMBIGUOUS_AI_EMPLOYEE`, if the name matches more than
  one— and **the request isn't sent**. It isn't checked in the preflight: the group is accepted and
  the failure shows up when it runs.
* **It can be classic or v2 (new engine).** A v2 reads the response with its powers: if one of them
  sends data to your system again, that response also counts toward the chain limit below. If v2
  employees are turned off on the platform, the response isn't processed and an error card shows up
  in the conversation. In a test conversation that card doesn't show up.
* **Only a `2xx` response with a body is read**, and the body is shown to a model: answer only with
  what the customer could end up learning.
* **The continuation runs afterwards**, in the background and with no guaranteed timeframe.
* **With another AI action in the group, the customer may get two replies.** If the same group
  includes `run_ai`, `ai_assistance` or `assign_ai_employee` with `run: true`, that action replies to
  the customer and the continuation writes again with what your system answered. Both can run **at
  the same time**, not necessarily one after the other. In a campaign, also, if the continuation takes
  the conversation first, the AI action's message may not go out. If you want a single reply, let
  the continuation give it.
* **The chain has a cap.** If the continuation dispatches to your system again, that response can
  continue the conversation too. A standalone `send_json` in an action group starts the chain from
  the beginning, so it gets **two continuations**. How many fit in each case is in that same
  webhooks section.

> [!NOTE]
>
> **The action itself is also being enabled in stages.** Until it's enabled on the platform, a group
> that includes it is rejected whole with `400 INVALID_REQUEST`, before anything runs; if the
> platform couldn't confirm whether it's enabled, it responds `500 FETCH_FAILED`, and you can retry.

> [!NOTE]
>
> **Availability:** continuing the conversation with the response is being enabled in stages **at
> the platform level**, not account by account. Until it's enabled, your system's response is logged
> and doesn't continue the conversation.

The business team can also use `send_json` in a campaign: there it sends **one request per
recipient** —see [how they arrive](https://docs.1to1ai.com/en/webhooks.md#what-your-endpoint-answers-can-continue-the-conversation)—.

## Executable example

A `send_json` on a conversation identified by phone and channel: it registers an order in your
system, and an AI employee confirms to the customer the number your system returns.

### Request

```bash theme={null}
curl -X POST "https://app.1to1ai.com/api/v1/public/{slug}/conversation/actions" \
  -H "Authorization: Bearer sk_1to1_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation": {
      "phone": "+525512345678",
      "channel": "ch_7A9K2M4Q"
    },
    "actions": [
      {
        "type": "send_json",
        "url": "https://erp.example.com/api/orders",
        "headers": { "Authorization": "Bearer <your system token>" },
        "body": "{\"sku\":\"A-100\",\"qty\":2,\"price\":150.50}",
        "response_processor": {
          "ai_employee": { "name": "Asistente de Ventas" },
          "instructions": "Confirm to the customer the order number the system returns."
        }
      }
    ]
  }'
```

### Response

`202 Accepted` — the group was accepted and runs in the **background**. The per-action result does
not travel in the response (query it later — see [How it
runs](https://docs.1to1ai.com/en/action-groups/overview.md#how-it-runs)).

```json theme={null}
{
  "status": "processing",
  "actions_accepted": 1
}
```

**status** `string`

Always `processing`: confirms the group was accepted and is running.

**actions\_accepted** `integer`

How many actions in the array were **admitted** for execution — not how many succeeded.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.