# Send a message TO a specific feature of a specific thing

`POST /api/2/things/{thingId}/features/{featureId}/inbox/messages/{messageSubject}`

Send a message with the subject `messageSubject` **to** the feature
specified by the `featureId` and `thingId` path parameter. The request
body contains the message payload and the `Content-Type` header defines
its type.

The HTTP request blocks until all acknowledgement requests are fulfilled.
By default, it blocks until a response to the message is available
or until the `timeout` is expired. If many clients respond to
the issued message, the first response will complete the HTTP request.

In order to handle the message in a fire and forget manner, add
a query-parameter `timeout=0` to the request.

Note that the client chooses which HTTP status code it wants to return. Ditto
will forward the status code to you. (Also note that '204 - No Content' status code
will never return a body, even if the client responded with a body).

### Who
You will need `WRITE` permission on the root "message:/" resource, or at least
the resource `message:/features/featureId/inbox/messages/messageSubject`. The receiving device needs `READ` permission on the resource.
Such permission is managed  within the policy which controls the access on the thing.

Authentication (security requirement alternatives):

```json
[
  {
    "OpenIDConnect": []
  },
  {
    "NginxBasic": []
  },
  {
    "Bearer": []
  }
]
```

- OpenIDConnect: openIdConnect. OpenID Connect Discovery URL. The placeholder is replaced by Swagger UI when configured.
- NginxBasic: http (basic). Eclipse Ditto sandbox demo user (demo1 ... demo9) + password (demo)
- Bearer: http (bearer). A JSON Web Token issued by a supported OAuth 2.0 Identity Provider.

Parameters:

- `thingId` (path, string, required) - The ID of a thing needs to follow the namespaced entity ID notation (see [Ditto documentation on namespaced entity IDs](https://www.eclipse.dev/ditto/basic-namespaces-and-names.html#namespaced-id)).
  Type: string

- `featureId` (path, string, required) - The ID of the feature - has to conform to RFC-3986 (URI)
  Type: string

- `messageSubject` (path, string, required) - The subject of the Message - has to conform to RFC-3986 (URI)
  Type: string

- `timeout` (query, integer, optional) - Contains an optional timeout (in seconds) of how long to wait for the message response and therefore block the
HTTP request. Default value (if omitted): 10 seconds. Maximum value: 60 seconds. A value of 0 seconds applies
fire and forget semantics for the message.
  Type: integer

- `requested-acks` (query, string, optional) - Contains the "requested acknowledgements" for this request as comma separated list. The HTTP call will
block until all requested acknowledgements were aggregated or will time out based on the specified `timeout`
parameter.

The default (if omitted) requested acks is `requested-acks=live-response` which will block the
HTTP call until a subscriber of the live message sends a response.
  Type: string

- `condition` (query, string, optional) - Defines that the request should only be processed if the given condition is met. The condition can be specified using RQL syntax. 
#### Examples
E.g. if the temperature is not 23.9 update it to 23.9:
* ```PUT /api/2/things/{thingId}/features/temperature/properties/value?condition=ne(features/temperature/properties/value,23.9)```

   `body: 23.9`

Further example conditions:
* ```?condition=eq(features/temperature/properties/unit,"Celsius")```
* ```?condition=ge(features/temperature/properties/lastModified,"2021-08-22T19:45:00Z")```
* ```?condition=gt(_modified,"2021-08-05T12:17:00Z")```
* ```?condition=exists(features/temperature/properties/value)```
* ```?condition=empty(features/temperature/properties/value)```
* ```?condition=and(gt(features/temperature/properties/value,18.5),lt(features/temperature/properties/value,25.2))```
* ```?condition=or(gt(features/temperature/properties/value,18.5),not(exists(features/temperature/properties/value))```
  Type: string

Request body: application/json

Payload of the message with max size of 250 kB. It can be any HTTP
supported content, including binary content.

Type: string

Example:

```json
""
```

Request body: application/octet-stream

Payload of the message with max size of 250 kB. It can be any HTTP
supported content, including binary content.

Type: string

Example:

```json
""
```

Request body: text/plain

Payload of the message with max size of 250 kB. It can be any HTTP
supported content, including binary content.

Type: string

Example:

```json
""
```

Responses:

- 202: The message was sent but not necessarily received by the feature
(fire and forget).

- 400: The request could not be completed. Possible reasons:
  * the `thingId` does not conform to the namespaced entity ID notation (see [Ditto documentation on namespaced entity IDs](https://www.eclipse.dev/ditto/basic-namespaces-and-names.html#namespaced-id)).
  * at least one of the defined path parameters is invalid.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 401: The request could not be completed due to missing authentication.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 403: The request could not be completed. Possible reasons:
 * the caller has insufficient permissions.
   You need `WRITE` permission on the resource `message:/features/{featureId}/inbox/messages/{messageSubject}`.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 404: The request could not be completed. Possible reasons:
  * the referenced thing does not exist.
  * the caller has insufficient permissions to interact with the messages of referenced thing.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 408: The request could not be completed due to timeout.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 412: A precondition for reading or writing the (sub-)resource failed. This will happen for write requests, if you
specified an If-Match or If-None-Match header, which fails the precondition check against the current ETag of
the (sub-)resource. For read requests, this error may only happen for a failing If-Match header. In case of a
failing If-None-Match header for a read request, status 304 will be returned instead.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 413: The size of the sent message is larger than the accepted limit of 250 kB.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 424: One or more acknowledgement requests in the parameter `requested-acks`
were not fulfilled.

Content type: application/json

Type: any

Example:

```json
{
  "acknowledgementLabel1": {
    "status": 200,
    "payload": "OK"
  },
  "acknnowledgementLabelN": {
    "status": 403,
    "payload": "Forbidden"
  }
}
```

- `acknowledgementLabel1` (optional)
  Type: any
  
  Example:
  
  ```json
  {
    "status": 200,
    "payload": "OK"
  }
  ```
  
  - `status` (required)
    Type: integer
    
    The HTTP status of the acknowledgement
  
  - `payload` (optional)
    Type: object | string | number | array | boolean
    
    The payload of the acknowledgement
    
    oneOf:
      Type: object
    
      Type: string
    
      Type: number
    
      Type: array
    
      Type: boolean

## Examples

### cURL

```bash
curl -X POST 'https://ditto.eclipseprojects.io/api/2/things/string/features/string/inbox/messages/string' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  --data-raw '""'
```

### JavaScript

```javascript
const response = await fetch('https://ditto.eclipseprojects.io/api/2/things/string/features/string/inbox/messages/string', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json',
  },
  body: '""',
});

const data = await response.text();
```

### Python

```python
import requests

response = requests.post(
    'https://ditto.eclipseprojects.io/api/2/things/string/features/string/inbox/messages/string',
    data='""'.encode('utf-8'),
    headers={
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json',
    },
)
print(response.text)
```
