# Messages

> Send a chat message to a client, in the same chat as Messages in the app.

Source: https://hubfit.com/developers/api/messages


Chat messages to a client, in the same chats as Messages in the app. Each coach on your team has their own chat with each client they message.

Endpoints:

- `POST /v1/clients/{clientId}/messages`: [Send a message to a client](https://hubfit.com/developers/api/messages#send-client-message)

## Message object

### Attributes

- `id` (string): The message's id in HubFit's chat.
- `text` (string)
- `sentAt` (timestamp)
- `client` (object)
  - `id` (string): Its unique ID.
  - `name` (string)

### Example

```json
{
  "id": "6ad6af693b64cf683b633c6b",
  "text": "Nice work this week! Your new program is in the app.",
  "sentAt": "2026-10-26T14:32:05.000Z",
  "client": {
    "id": "6ad6af41d3199442d31b2743",
    "name": "Jordan Miller"
  }
}
```

## Send a message to a client

`POST https://api.hubfit.com/v1/clients/{clientId}/messages`

Sends a chat message to the client as you, the coach the key belongs to, from your own chat with them, as sending one in the app does. The client sees it in their app straight away and is notified as for any chat message. If you haven't messaged the client before, this starts your chat with them. Each call sends another message, so send an `Idempotency-Key` to retry safely. A client whose messaging is turned off in HubFit answers `409 messaging_disabled`. Each coach can send 30 messages a minute and 500 a day, across the API and the MCP server; past either it's a `429` naming that limit, which sends nothing and leaves the `Idempotency-Key` free for the retry. Requires `messages:write`.

### Headers

- `Idempotency-Key` (string): Any unique string, such as a UUID, up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the write. See [Idempotency](https://hubfit.com/developers/idempotency).

### Path parameters

- `clientId` (string, required): The client's `id`.

### Body parameters

- `text` (string, required): The message. Can't be blank.

### Returns

The message, as sent.

### Example request

cURL:

```bash
curl -X POST https://api.hubfit.com/v1/clients/6ad6af41d3199442d31b2743/messages \
  -H "Authorization: Bearer $HUBFIT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Nice work this week! Your new program is in the app."
  }'
```

Node.js:

```javascript
const response = await fetch("https://api.hubfit.com/v1/clients/6ad6af41d3199442d31b2743/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.HUBFIT_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    text: "Nice work this week! Your new program is in the app.",
  }),
});

const { data } = await response.json();
```

Python:

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.hubfit.com/v1/clients/6ad6af41d3199442d31b2743/messages",
    headers={"Authorization": f"Bearer {os.environ['HUBFIT_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
        "text": "Nice work this week! Your new program is in the app.",
    },
)

data = response.json()["data"]
```

### Example response (201 Created)

```json
{
  "data": {
    "id": "6ad6af693b64cf683b633c6b",
    "text": "Nice work this week! Your new program is in the app.",
    "sentAt": "2026-10-26T14:32:05.000Z",
    "client": {
      "id": "6ad6af41d3199442d31b2743",
      "name": "Jordan Miller"
    }
  }
}
```
