# Ingesting events

Sending data to Better Stack Warehouse is as easy as sending an HTTP request.

This endpoint allows you to ingest a single event or a list of events. The events can be encoded in JSON or preferably in a more efficient MessagePack.

Start by [creating a Warehouse source](https://warehouse.betterstack.com/team/0/sources/new ";_blank") in the data region of your choice.

[endpoint]
base_url = "https://$INGESTING_HOST/"
method = "POST"

[[header]]
name = "Content-Type"
description = "Either application/json, application/msgpack, or application/x-ndjson"
required = true
type = "string"

[[header]]
name = "Authorization"
description = "Bearer `$SOURCE_TOKEN`"
required = true
type = "string"

[[body_param]]
name = "Multiple events"
description = "An array of events encoded in JSON or MessagePack, or newline-delimited JSONs of events"
required = true
type = "array"

[[body_param]]
name = "Single event"
description = "A single event encoded in JSON or MessagePack"
required = true
type = "object"
[/endpoint]

[responses]
[[response]]
status = 202
description = '''The events were successfully ingested.'''
body = ''''''

[[response]]
status = 403
description = '''You provided an invalid source token.'''
body = '''Unauthorized'''

[[response]]
status = 406
description = '''The body is not a valid JSON or MessagePack.'''
body = '''Couldn't parse JSON content.'''

[[response]]
status = 413
description = '''The body is too large (over 20 MiB).'''
body = '''payload reached size limit'''
[/responses]

## Examples

### Single event

Send a single event using cURL:

[code-tabs]
```shell
[label JSON]
curl -X POST https://$INGESTING_HOST \
     -H "Authorization: Bearer $SOURCE_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"message":"My first event","nested":{"values":123}}'
```
```shell
[label NDJSON]
curl -X POST https://$INGESTING_HOST \
     -H "Authorization: Bearer $SOURCE_TOKEN" \
     -H "Content-Type: application/x-ndjson" \
     -d '{"message":"My first event","nested":{"values":123}}'
```
```shell
[label MessagePack]
# Python is required to prepare the binary data in this example
python3 -c 'import msgpack; \
     print(msgpack.packb( \
          {"message":"My first event","nested":{"values":123}} \
     ).hex())' \
     | xxd -r -p \
     | curl -X POST https://$INGESTING_HOST \
          -H "Authorization: Bearer $SOURCE_TOKEN" \
          -H "Content-Type: application/msgpack" \
          --data-binary @-
```
```javascript
[label Javascript]
fetch('https://$INGESTING_HOST', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer $SOURCE_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(
    {"message": "My first event", "nested": {"values": 123}}
  ),
})
.then(res => { if (!res.ok) console.error('Err:', res.status) })
.catch(error => console.error('Err:', error.message));
```
[/code-tabs]

### Multiple events

Send multiple events using cURL:

[code-tabs]
```shell
[label JSON]
curl -X POST https://$INGESTING_HOST \
     -H "Authorization: Bearer $SOURCE_TOKEN" \
     -H "Content-Type: application/json" \
     -d '[{"message":"A"},{"message":"B"}]'
```
```shell
[label NDJSON]
curl -X POST https://$INGESTING_HOST \
     -H "Authorization: Bearer $SOURCE_TOKEN" \
     -H "Content-Type: application/x-ndjson" \
     -d $'{"message":"A"}\n{"message":"B"}'
```
```shell
[label MessagePack]
# Python is required to prepare the binary data
python3 -c 'import msgpack; \
     print(msgpack.packb( \
          [{"message":"A"},{"message":"B"}] \
     ).hex())' \
     | xxd -r -p \
     | curl -X POST https://$INGESTING_HOST \
          -H "Authorization: Bearer $SOURCE_TOKEN" \
          -H "Content-Type: application/msgpack" \
          --data-binary @-
```
```javascript
[label Javascript]
fetch('https://$INGESTING_HOST', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer $SOURCE_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(
    [{"message": "A"}, {"message": "B"}]
  ),
})
.then(res => { if (!res.ok) console.error('Err:', res.status) })
.catch(error => console.error('Err:', error.message));
```
[/code-tabs]

## Sending timestamps

By default, the time of the event will be the time of receiving it. You can override this by including a field `dt` containing the event time either as:

- [UNIX time](https://en.wikipedia.org/wiki/Unix_time) in whole seconds, milliseconds, or nanoseconds.
`1672490759`, `1672490759123`, `1672490759123456000`
- String formatted according to [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339).
`2022-12-31T13:45:59.123456Z`, `2022-12-31 13:45:59.123456+02:00`

Alternatively, you can use ISO 8601, as it will most likely use a format compatible with RFC 3339. In MessagePack, you can also use the [timestamp extension type](https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type).

In case the timestamp can't be parsed, we save it as a string, but revert to using the reception time as the event time.

```shell
[label JSON]
curl -X POST https://$INGESTING_HOST \
     -H "Authorization: Bearer $SOURCE_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"message":"I have arrived on time","dt":"2023-08-09 07:03:30+00:00"}'
```

## Request limits

The maximum allowed size of a single request that might contain many events is 10 MiB of compressed data.

Each event is limited to 1 MiB maximum size, but we recommend keeping a single event under 100 KiB for the best experience.

There is **no limit to the number of requests** you can send.
