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

# Basic API

> Reference for the /basic API endpoints, protected by Basic auth and used with a valid JSON API token.

## Introduction

This page describes `/basic` API endpoints. These endpoints are protected by
`Basic auth` and can only be used by a valid JSON API Token.

You need an *API Token* which can be requested from [support@kero.chat](mailto:support@kero.chat).

The examples in this page use variables that you'd want configure on a terminal
session:

```sh theme={null}
API_URL=https://api.kero.chat/rbm
AGENT_ID='<your agent ID>'
BASIC_AUTH="Authorization: Basic $API_TOKEN_BASE_64"
```

### API usage rules

1. Adding a *nullable field* to any API request is not considered a breaking change but will bump the minor version number.
2. Adding a *new field* to any API response is not considered a breaking change but will bump the minor version number.  It is expected that your integration code can handle such additions.

These rules apply to all Kero APIs.

## Batch create

Create a new batch.

Note that after you created a new batch, you must
[submit the batch](#batch-submit) to send messages.

You should consider using the [agent submit](https://kero.chat/help/kero-developer-pages/agent-api.md#message-submit)
endpoint to send transactional messages. The batch feature on this API is for
use by brand agents that are approved to send messages in bulk. That being said,
when those transactional messages are not time critical and are queued on your
side, batching could be the best fit for your case.

Endpoint: `POST /basic/batch`

**Request schema**

```ts theme={null}
{
    agentId: string,
    smsSenderId: string|null,
    content: MessageContent|null,
    template: TemplateContent|null,
    userRef: string|null,
    recipients: {
        msisdn: string,
        userRef: string|null,
        values: string[]|null,
    }[],
    campaignName: string|null,
    isMarketing: bool|null
}
```

1. The `agentId` identifies the [Brand Agent](#brand-agent-list) that will be
   used to send the messages in the batch.
2. Either the `content` of the `template` property must have a value, but not
   both.
3. The `content` property contains a
   [Message Content](https://kero.chat/help/kero-developer-pages/object-schemas.md#message-content) object.
4. The `template` property contains a
   [Template Content](https://kero.chat/help/kero-developer-pages/object-schemas.md#template-content) object
5. When the `template` is constrained to a specific brand agent the `agentId`
   provided here must match the one specified by the template.
6. The `content` or the `template` must contain message content for the
   `providerType` associated with the `agentId`.
7. The `recipients` property recipient is identified by a `msisdn` and an array
   of `values`.
8. In the `content`, or in the `template.model` you can use one or more
   *place-holders*.
9. A `place-holder` has the format `{{k}}` were `k` is the zero based index. For
   example, the snippet `Hello {{0}} {{1}}` contains two place-holders.
10. When you use place-holders, the `values` array must have enough items to
    transform all place-holders. For the example snippet,
    `values=["Bobby", "Smith"]` will be transformed to send the message text
    `Hello Bobby Smith`.
11. The `userRef` property can be specified for the batch or on the recipient
    level, not both.
12. Specify `"userRef": "auto"` if you'd like to use the generated `batchId` in
    the `userRef`. The reference of each message will be the prefixed by the
    `batchId`, followed by a sequence number.
13. The `userRef` value is optional. When it is supplied, it cannot be an empty
    string, and must have a length of `36` or less.
14. The total size of the request must be less than 6 MB. If you have no
    place-holder, you can send around `80 000` messages per batch. However, if
    you use batch `userRef` for lookup purposes it is best to limit the size of a
    batch to `10 000` messages.
15. When you specify a `campaignName`, a *campaign instance* will be created when
    you submit the batch. A batch with a campaign name cannot have any `userRef`
    values.
16. If the `smsSenderId` is not `null` this value takes precedence over the
    sender ID that might be provided on the template.  If possible for your use case, a better approach is to use `null` here and instead use an SMS Brand Agent with a specific sender ID.
17. The `inMarketing` flag should be set to `true` if the batch contains marketing messages.

**Response schema**

```ts theme={null}
{
  batchId: string;
}
```

1. Use this `batchId` to submit the batch for processing.

**Example 1 - content based**

Create a file called `batch-001.json` with this content.

```json theme={null}
{
    "agentId": your-agent-id
    "content": {
        "rcs": {
            "contentMessage":{
                "text": "Welcome {{0}}, your color is {{1}}"
            }
        }
    },
    "recipients": [
        {"msisdn": "+000723111", "values": ["Bobby","Red"]},
        {"msisdn": "+000723121", "values": ["Sue","Blue"]}
    ]
}
```

Now you can create a batch from this file:

```sh theme={null}
JSON_H="Content-Type: application/json"
curl -s -H $BASIC_AUTH -H $JSON_H $API_URL/basic/batch -d @batch-001.json | jq
```

You can use `jq` to get the batch ID:

```sh theme={null}
BATCH_ID=`curl -s -H $BASIC_AUTH -H $JSON_H $API_URL/basic/batch -d @batch-001.json | jq -r '.batchId'`
echo "Your batch ID is $BATCH_ID"
```

**Example 2 - template based**

Here we use the template from the [template create](#message-template-create)
example. Here we have two template parameters: `firstName` and `color`.

Create a file called `batch-002.json` with this content:

```json theme={null}
{
    "agentId": your-agent-id,
    "template": {
        "id": "my-example",
         "model": {
            "firstName" : "{{0}}",
            "color": "{{1}}"
        }
    },
    "recipients": [
        {"msisdn": "+000723111", "values": ["Bobby","Red"]},
        {"msisdn": "+000723121", "values": ["Sue","Blue"]}
    ]
}
```

Notice that the model maps the template parameters to indexes in the `values`
array.

```sh theme={null}
JSON_H="Content-Type: application/json"
curl -s -H $BASIC_AUTH -H $JSON_H $API_URL/basic/batch -d @batch-001.json | jq
```

## Batch submit

Submits a previously created batch to send a message to every recipient.

Endpoint: `GET /basic/batch/:batch_id/submit`

**Response schema**

```ts theme={null}
{
  message: string;
}
```

1. The message is `ok` when the submission was successful.
2. This endpoint is idempotent: an appropriate `message` is returned when a
   duplicate submit is made.

**Example**

```sh theme={null}
curl -s -H $BASIC_AUTH $API_URL/basic/batch/$BATCH_ID/submit
```

## Brand agent list

Returns the array of brand agents configured for your account.

Endpoint: `GET /basic/agents`

**Response schema**

```ts theme={null}
{
    id: string,
    name: string,
    providerType: "RCS"|"WhatsApp"|"SMS",
}[]
```

**Example**

```sh theme={null}
curl -H $BASIC_AUTH -X GET $API_URL/basic/agents | jq
```

## Brand agent token

Endpoint: `GET /basic/agent-token/:agent_id`

Returns a token that is used for authentication on the Agent API.

**Response schema**

```ts theme={null}
{
    agentToken: string,
    expiry: timestamp,
    expiryEpoch: number
}
```

1. The `agentToken` is the token you use to construct the bearer auth header,
   e.g. `AGENT_AUTH="Authorization: Bearer $AGENT_TOKEN`
2. The two `expiry` properties represent the same date value. The value for
   `expiryEpoch` is `expiry` expressed in
   [epoch](https://en.wikipedia.org/wiki/Epoch_\(computing\)) seconds.

**Example**

```sh theme={null}
curl -s -H $BASIC_AUTH $API_URL/basic/agent-token/$AGENT_ID
```

## Campaign query

List the most recent campaigns that match the criteria.

Endpoint: `POST /basic/campaign/query`

**Request schema**

```ts theme={null}
{
    time: {
        from: timestamp|null,
        until: timestamp|null
    } | null,
    limit: number|null
}
```

1. The value for `time` is optional - if not supplied the response contains the
   most recent campaigns.
2. When provided, the resolution of `from` and `until` must be *minutes* or
   finer. Example: `2023-09-01T12:44:00Z`
3. The `from` must be less than `until`.
4. The `limit` specifies the maximum amount of objects to return. The default is
   `10`, and it must be less than or equal to `10000`.

**Response schema**

```ts theme={null}
{
    id: string,
    name: string,
    agentId: string,
    created: timestamp,
    messageCount: number,
}[]
```

**Example**

Fetch the `10` most recent campaigns:

```sh theme={null}
JSON_H="Content-Type: application/json"
curl -s -H $BASIC_AUTH -H $JSON_H $API_URL/basic/campaign/query -d '{}' | jq
```

## Campaign detail

Fetch details of a specific campaign.

Endpoint: `GET /basic/campaign/:msg-id`

**Response schema**

```ts theme={null}
{
    id: string,
    name: string,
    agentId: string,
    created: timestamp,
    messageCount: number,
}[]
```

**Example**

```sh theme={null}
curl -H $BASIC_AUTH $API_URL/basic/campaign/62238a49dcf6c | jq
```

## Campaign delete

Delete a campaign.

Endpoint: `DELETE /basic/campaign/:id`

1. This endpoint is idempotent: if a campaign with this `id` does not exist, the
   endpoint does not return an error.

```sh theme={null}
curl -X DELETE -H $BASIC_AUTH $API_URL/basic/campaign/62238a49dcf6c
```

## Message template create

Create a message template.

Endpoint: `POST /basic/template`

**Request Schema**

```ts theme={null}
{
    id: string,
    name: string,
    content: MessageContent,
    agentId: string|null,
    smsSenderId: string|null,
}
```

1. The `id` will be used when sending messages. Its value is limited to lower
   case letters (`a` to `z`), numbers (`0` to `9`) and may contain dashes (`-`).
   The value must start with a letter.
2. The value for `name` must be supplied and cannot be an empty string.
3. The `content` property contains a
   [Message Content](https://kero.chat/help/kero-developer-pages/object-schemas.md#message-content).
4. The `content` may contain `parameter-references`.
5. A `parameter-reference` has the format `{{p}}` where `p` is may have upper or
   lower case letters (`a` to `z` or `A` to `Z`) and underscore (`_`). An
   example parameter value is `{{home_address}}`.
6. The `agent_id` optionally associates the template with a *brand agent*.
7. When a template is associated with a brand agent you cannot use it to send
   messages from any other brand agent.
8. When the `agent_id` is not null or empty, it should identify a Brand Agent
   from the [brand agent list](#brand-agent-list). However, it is possible to
   provide the ID of a brand agent that is not yet registered.
9. When supplied the `smsSenderId` will be used to send SMS fallback messages.  A better alternative is to specify the sender ID on the SMS Brand Agent that is used as fallback.

**Response Schema**

The response is a `Template` object. It is the same as the request, with one
additional property.

```ts theme={null}
{
    id: string,
    name: string,
    content: {
            rcs: object,
            sms: string|null
        },
    agentId: string|null,
    parameters: string[]
}
```

1. The `parameters` are the values that must be supplied when using the
   templates. These are collected from the `parameter-references` used in the
   content.

**Example**

Create a file called `template-001.json` with this content.

```json theme={null}
{
  "id": "my-example",
  "name": "Just an example",
  "content": {
    "rcs": {
      "contentMessage": {
        "text": "Welcome {{firstName}}, your color is {{color}}"
      }
    }
  }
}
```

Now you can create a template from this file:

```sh theme={null}
JSON_H="Content-Type: application/json"
curl -s -H $BASIC_AUTH -H $JSON_H $API_URL/basic/template -d @template-001.json
```

## Message template update

Update a message template.

Endpoint: `PUT /basic/template`

**Request Schema**

The same object as the [create endpoint](#message-template-create) with this
additional rule:

1. The `id` identifies an existing template.

**Response Schema**

Same response as the [create endpoint](#message-template-create).

## Message template details

Get the details of a message template.

Endpoint: `GET /basic/template/:id`

**Response Schema**

Same response as the [create endpoint](#message-template-create).

## Message template list

Endpoint: `GET /basic/templates`

Returns the array of your message templates.

**Response Schema**

```ts theme={null}
Template[]
```

The `Template` object is defined in the
[create endpoint](#message-template-create).

## Message template delete

Delete a template.

Endpoint: `DELETE /basic/template/:id`

1. This endpoint is idempotent: if a template with this `id` does not exist, the
   endpoint does not return an error.

## Message queries

Get the list of the most recent messages that match the criteria.

Endpoint: `POST /basic/message/query`

**Request schema**

```ts theme={null}
{
    filter: {time: TimeFilter} | {userRef: ReferenceFilter} | null
    limit: number|null
}
```

1. You can filter by `time` or by `userRef`, not both.
2. If you do not supply a filter, the most recent messages will be returned.
3. A maximum count contained in the result is the value of `limit`. The default
   is `10`.
4. The `limit` must be less than or equal to `10000`.

The `TimeFilter` schema looks like this:

```ts theme={null}
{
    from: string|timestamp,
    until: string|timestamp,
}
```

1. You can truncate the `from` and `until` values. The system uses the string
   comparison operator on the input.
2. A value for `from` or `until` must be supplied. The defaults are `2000` and
   `9999` respectively.
3. Ensure that `from` is always strictly less than `until`.

Reference filter:

```ts theme={null}
{
  value: string;
  method: "Exact" | "BeginsWith" | null;
}
```

1. The `value` cannot be an empty string.
2. This filter matches `value` against the message `ref` property.
3. The `method` specifies the kind of match. The default is `Exact`.

**Response schema**

```ts theme={null}
{
    id: string,
    agentId: string,
    created: timestamp,
    msisdn: string,
    userRef: string | null,
    sendStatus: null | string,
    sendStatusReason: null | string
}[]
```

1. The `sendStatus` and `sendStatusReason` properties are filled in during the
   message transmission process. For test messages these values are not
   available.
2. The `sendStatusReason` has a value when the `sendStatus` is such that
   additional information is required. For example, when `sendStatus` is
   `failed` `sendStatusReason` will give more information.
3. Messages older than `62` days are not available to this endpoint.

**Example**

Here we fetch all messages created during the first quarter of 2025. Take note
that the `untilTime` value excludes April, but includes March 2024.

```sh theme={null}
JSON_H="Content-Type: application/json"
CRIT='{"filter":{"time": {"from": "2024-01", "until": "2025-04"}}}'
curl -s -H $BASIC_AUTH -H $JSON_H $API_URL/basic/message/query -d $CRIT | jq
```

## Message detail

Fetch details of a specific message.

Endpoint: `GET /basic/message/:msg-id`

**Response schema**

```ts theme={null}
{
  id: string,
  agentId: string,
  content: object,
  created: timestamp,
  msisdn: string
  sendStatus: string | null
  sendStatusReason: string | null
  sendStatusTime: timestamp | null
  userId: string | null
}
```

**Example**

```sh theme={null}
curl -H $BASIC_AUTH $API_URL/basic/message/174a9eca-51d1-48e9-8999-73bfa2d35008
```

## Reply query

Get the list of the most recent replies that match the criteria.

Endpoint: `POST /basic/reply/query`

**Request schema**

```ts theme={null}
{
  time: TimeFilter | null;
  msidn: string | null;
  limit: number | null;
}
```

1. If you do not supply a time, the most recent messages will be returned.
2. The `TimeFilter` is described the [message query](#message-query) endpoint.
3. A maximum count contained in the result is the value of `limit`. The default
   is `10`.
4. The `limit` must be less than or equal to `10000`.

Time filter:

```ts theme={null}
{
    from: string|timestamp,
    until: string|timestamp,
}
```

1. You can truncate the `from` and `until` values. The system uses the string
   comparison operator on the input.
2. If you specify a `time`, a value for `from` or `until` must be supplied. The defaults are `2000` and
   `9999` respectively.
3. Ensure that `from` is always strictly less than `until`.

**Response schema**

```ts theme={null}
{
    agentId: string,
    created: timestamp,
    msisdn: string,
    replyType: `Text`|`Item`,
    replyValue: string
}[]
```

**Example**

Here we fetch all replies created during the first quarter of 2025. Take note
that the `untilTime` value excludes April, but includes March 2024.

```sh theme={null}
JSON_H="Content-Type: application/json"
CRIT='{"time": {"from": "2024-01", "until": "2025-04"}}'
curl -s -H $BASIC_AUTH -H $JSON_H $API_URL/basic/reply/query -d $CRIT | jq
```


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