# Ingesting logs

You can use Better Stack even if there's no official library for your programming language by sending your logs to our HTTP API.

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

[endpoint]
base_url = "/"
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 log events encoded in JSON or MessagePack, or newline-delimited JSONs of log events"
required = true
type = "array"

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

[responses]
[[response]]
status = 202
description = '''The event was, or the events were successfully logged.'''
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 log line 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":"logs is ready","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":"logs is ready","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":"logs is ready","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 @-
```
[/code-tabs]

### Multiple events

Send multiple log lines 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 @-
```
[/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, which may contain many events, is 10 MiB of compressed data.

Each log record is limited to 10 MiB maximum uncompressed size, but we recommend keeping a single log record under 100 KiB for the best experience.

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