## 1. Project Overview & Quickstart (vectordotdev/DOCUMENTING)

# DOCUMENTING

Open-source repository vectordotdev/DOCUMENTING

### Repository Details
- **Repository:** [vectordotdev/DOCUMENTING](https://github.com/vectordotdev/DOCUMENTING)
- **Primary Language:** Code

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (vectordotdev/docs)

## File: README.md

# What Is Timber?



[Timber](https://timber.io/) is a hosted service for aggregating logs across your entire stack - [any language](setup/languages/), [any platform](setup/platforms/), [any data source](setup/log-forwarders/). Timber was designed with a strong focus on simplicity, real-time access, and structured data.

---

## File: clients/web-app/README.md

---
---

# Web App

Use Timber within any modern browser.

## Accessing

In your browser, navigate to [**https://app.timber.io**](https://app.timber.io).

## Layout



### 1. Organization Switcher

Easily switch between and manage multiple organizations.

### 2. Main Navigation

Contains the [main sections](./#sections) of the apps.

### 3. Account & Help

Account preferences, sign out, and get help.

## The Console



The console is the the first icon in the [main navigation](./#2-main-navigation). It is the main area where you'll explore your logs. It's comprised of views that serve as windows into your data. These are represented by tabs.

### Live Tail View

The [live-tail view](../../usage/live-tailing.md) is designed to give you real-time access into your log data with powerful search capabilities. Learn more in our [live-tail section](../../usage/live-tailing.md).



### Graph View

The [_graphing view_](../../usage/graphing.md) lets you visualize your log data. Learn more in our [graphing section](../../usage/graphing.md).



## Sources

The [sources section](../../usage/source-management.md) lets you [manage your log sources](../../usage/source-management.md).



## Alerts

The [alerts section](../../usage/alerting.md) let you manage all of your alerts and notification preferences.



## Settings

The [settings section](../../usage/account-management/) lets you manage all of your organization settings.

## Usage

{% page-ref page="../../usage/live-tailing.md" %}

{% page-ref page="../../usage/sql-querying.md" %}

{% page-ref page="../../usage/graphing.md" %}

{% page-ref page="../../usage/saved-views.md" %}

...and more. Checkout out the [main usage section](../../usage/live-tailing.md) for more guides and tutorials.

---

## File: clients/cli/README.md

---
---

# CLI

Timber integrates with the command line through the [`timber` command line utility](https://github.com/timberio/cli), allowing you to access and search your logs directly from your terminal.

## Features

* Static binary with no dependencies
* [Live-tail & search your logs](../../usage/live-tailing.md)
* [SQL query your logs](../../usage/sql-querying.md)
* List organizations
* [List sources / applications](../../usage/source-management.md)
* Issue authenticated requests to the [Timber API](https://docs.api.timber.io)

## Installation

The Timber CLI ships as a static binary with no dependencies.

### Mac OS

Timber is easily installed through the [homebrew package manager](https://brew.sh/):

```bash
brew tap timberio/brew && brew install timber
```

You can update `timber` over time via:

```text
brew update && brew upgrade timber
```

### Pre-built binaries

If you're not on Mac, or prefer not to use [homebrew](https://brew.sh/), you can install one of our pre-built binaries. These can be found in the [releases section](https://github.com/timberio/cli/releases) of the [`cli` repository](https://github.com/timberio/cli):

* [Darwin AMD64](https://github.com/timberio/cli/blob/master)
* [FreeBSD AMD64](https://github.com/timberio/cli/blob/master)
* [Linux AMD64](https://github.com/timberio/cli/blob/master)
* [Linux ARM](https://github.com/timberio/cli/blob/master)
* [Linux ARM64](https://github.com/timberio/cli/blob/master)
* [NetBSD AMD64](https://github.com/timberio/cli/blob/master)
* [OpenBSD AMD64](https://github.com/timberio/cli/blob/master)

### Building From Source

If all else fails, you can build `timber` from source. Building from source requires the [`go` runtime](https://golang.org/doc/install):

```bash
git clone git@github.com:timberio/cli.git timber
cd timber
go build
./timber help
```

We recommend moving `timber` into your `$PATH`.

## Configuration

### Authentication

To use the Timber CLI you'll need to [create an API key](../../usage/account-management/api-keys.md#creating). Simply copy your API key and run `timber auth [api_key]`, replacing `[api_key]` with your new API key value.

```bash
timber auth [api_key]
```

This will store your API key in the `~/.timber` folder. Going forward, this key will be used for all timber commands. Alternatively, you can supply the `--api-key` flag with each command or set the `TIMBER_API_KEY` environment variable.

### Switching Between Organizations

The Timber CLI offers support for switching between multiple organizations:

1. Run `timber auth list` to list your API keys
2. Run `timber auth switch [org_id]` to switch to another API key.

If you don't see your API key, [add it as described above](./#authentication).

### ANSI Coloring

By default, Timber will use [ANSI coloring](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors), you can disable this with the `--monochrome-output` flag or by setting the `TIMBER_NO_COLOR` env var.

## Updating

### Mac OS

```bash
brew update
brew upgrade timber
```

### Other

Simply delete the `timber` binary and [re-install it](./#installation).

## Commands

Commands and options can be accessed with the `timber help` command:

```text
NAME:
   timber - Command line interface for the Timber.io logging service

USAGE:
   timber [global options] command [command options] [arguments...]

VERSION:
   0.2.0

COMMANDS:
     auth         Manage authentication for the Timber CLI
     tail, t      Live tails logs
     sources      Manage your Timber sources
     sql-queries  Manage SQL queries
     views        Manage your saved views (only console views are supported in the CLI)
     api          Issue authenticated requests to the Timber API (http://docs.api.timber.io)
     help, h      Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --api-key value, -K value    Your timber.io API key [$TIMBER_API_KEY]
   --color-output, -C           Set to force color output even if output is not a color terminal [$TIMBER_COLOR]
   --max-columns value          Maximum number of columns to display in a table (default: 7) [$TIMBER_MAX_COLUMNS]
   --max-column-length value    Maximum length of a single column value (default: 20) [$TIMBER_MAX_COLUMNS]
   --max-per-page value         Maximum number of items to display per page (default: 25) [$TIMBER_MAX_PER_PAGE]
   --monochrome-output, -M      Disable color output [$TIMBER_NO_COLOR]
   --debug, -D                  Output debug messages [$TIMBER_DEBUG]
   --host value, -H value       Timber.io host, useful for testing (default: "https://api.timber.io") [$TIMBER_HOST]
   --time-zone value, -Z value  Time zone, such as "Local", "UTC", or "America/New_York" (default: "Local") [$TIMBER_TIME_ZONE]
   --help, -h                   show help
   --version, -v                print the version
```

## Usage

{% page-ref page="../../usage/live-tailing.md" %}

{% page-ref page="../../usage/sql-querying.md" %}

...and more. Checkout out the [main usage section](../../usage/live-tailing.md) for more guides and tutorials.

---

## File: guides/README.md

---
---

# Guides

---

## File: guides/reducing-log-volume.md

---
---

# Reducing Log Volume

Reducing log volume not only has the benefit of reducing your cost, but it also reduces log noise. Below are tips we provide to customers wondering how to reduce their log volume. They're ordered by their effort to return ratio.

## 1. Filter Logs You Don't Need

When it comes to log filtering, you have two choices: filter application side or filter Timber side. We highly recommend starting with the application side.

### Filtering Application Side

Filtering your logs on the application is much more efficient because it reduces the log burden on your app, avoiding the overhead of sending the log data to Timber entirely. There are a few ways you can do this:

1. Simply remove the log statement. If you don't find it helpful then it makes sense to remove it entirely.
2. Move the log statement to a lower level, such as `debug`, and then configure your app to log at a higher level, such as `info`. This is a great strategy because you don't lose the ability to generate that log if and when you need it. You can simply drop your log level down to `debug`.

### Filtering Timber Side

If you find that you cannot filter your log on the application side then we recommend filtering it on the Timber side. Timber offers a [log filtering feature](../usage/filtering-logs.md) that allows you to drop logs containing specific key words. More information on that here:

{% page-ref page="../usage/filtering-logs.md" %}

## 2. Sample Logs

As an alternative to filtering logs entirely, you can sample them at a rate. This simply reduces the volume, and at high numbers a small subset of logs usually provide enough visibility as to not reduce utility. Depending on your language, your sampling implementation will will differ. To keep things simple, we recommend starting with random sampling. For example, in Ruby you could do:

```ruby
if Random.rand(3) == 0
    logger.info("Log message")
end
```

This effectively reduces the log volume to 30% of the original. More advanced sampling strategies will rate limit logs based on time, or bucket logs based on a context factor.

## 3. Reduce Log Size

If 1 and 2 above do not solve your problem, then you'll need to look at ways to trim your log size. Because Timber is focused on structured logging, there is possibility that your log metadata could be larger than expected. In this case, we recommend trimming metadata to only the attributes necessary.

---

## File: guides/sending-logs-to-timber.md

---
---

# Sending Logs To Timber

You'll notice Timber offers a [variety of methods](sending-logs-to-timber.md#integration-methods) for sending logs to Timber. While flexible, this can be confusing, and often it's hard to understand which method is best. This guides serves to help in that process, helping you to walk away with the best integration method for your scenario.

## Integration Methods

Timber attempts to be as flexible as possible, attempting to integrate with a variety of platforms, systems and languages. You can send log data to Timber by choosing your preferred integration method. To better understand which method you should use please continue reading.

{% page-ref page="../setup/languages/" %}

{% page-ref page="../setup/log-forwarders/" %}

{% page-ref page="../setup/operating-systems/" %}

{% page-ref page="../setup/platforms/" %}

## In-App Log Delivery

In-app log delivery refers to the process of sending application log data to Timber directly within your app. For example, using [Timber's Ruby library](../setup/languages/ruby/), you can send your Ruby app's logs directly to Timber without writing to `STDOUT` or a file. While simple, this method has a number of drawbacks:

### Pros

1. Simple to setup.
2. Does not require system level changes or installations.
3. If you're using one of [Timber's libraries](../setup/languages/) we'll automatically capture context and structure your logs.

### Cons

1. Potential for data loss. The Timber libraries build a small in-memory buffer of data in order to send log data in batches. Our libraries are configured to flush at 950kb or after 2 seconds. If your app crashes unexpectedly, we'll attempt a final delivery, but it is not guaranteed depending on the crash reason. Therefore, it is possible to lose up to 2 seconds of data immediately before the crash.
2. Less reliable. Delivery failures are retried 3 times and then discarded to handle back-pressure. This ensures Timber does not disrupt your application's performance, but it also means that this log data is lost.
3. Less stable. Because you're coupling log delivery with your application there is the possibility that log delivery will disrupt your application's stability. While Timber has taken every measure possible to prevent this, many times it it outside of our control.

## Platform & System Log Delivery

Platform & system log delivery refers to the process of sending log data to Timber outside of an application, such as tailing a file or forwarding Syslog logs to Timber.

### Pros

1. Durable. If you configure your application to write to disk your log data is durable. It will survive application crashes and restarts.
2. Reliable. Log delivery is more reliable since you're writing log data to disk and using that as a buffer. Failures can be indefinitely retried until they succeed, allowing you to continue processing through the remaining buffer on disk.
3. Stable. Log delivery is decoupled from your application removing the risk that it could affect application stability.
4. Follows the [12 factor methodology](https://12factor.net/) best practices.

### Cons

1. Difficult. This method involves more steps and requires system-level operational experience to connect all of the pieces.
2. Slower. This method is slower since there are more steps and configuration.

## Which Method Is Best?

For serious production systems we _highly_ recommend shipping logs external from your application by integrating directly with your platform or system. It is worth the time and effort to invest in this method to ensure you have log data when you need it.

For everyone else, our [language libraries](../setup/languages/) should be sufficient, especially for applications just starting out. This allows you to get up and running with very little effort and time.

---

## File: guides/structured-logging-best-practices.md

---
---

# Structured Logging Best Practices

{% hint style="info" %}
Timber provides [language level libraries ](../setup/languages/)that make structured logging a breeze. If you haven't already, please [check them out](../setup/languages/).
{% endhint %}

Timber has a strong focus on structured logging; modern developers are starting to see their logs as structured events not text. And while the benefits of structured logs are obvious, it's not always obvious how to get started. After working with thousands of companies, and using Timber heavily within Timber itself, this document collates our structured logging best practices.

## What Is Structured Logging?

This is best explained with an example. Let's look at your basic [Rails](https://rubyonrails.org/) HTTP response log. It typically looks something like this:

```text
2019-02-04T12:23:34Z INFO Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)
```

While this is nice to see, it's incredibly unhelpful. To improve the utility of this log, let's add some context:

```text
2019-02-04T12:23:34Z [host=34.235.155.83 user_id=5 path=/welcome method=GET] INFO Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)
```

Better, but you can start to see the problems with this direction:

1. This format is arbitrary. Custom parsing is required to extract the attributes.
2. It's not human friendly, the log is noisy and hard to read.
3. There's no guarantee this format won't change, breaking downstream consumption.

This is why developers turn to structured logging. Wouldn't it be nice if this log event was represented as a simple JSON document?

```javascript
{
    "dt": "2019-02-04T12:23:34Z",
    "level": "info",
    "message": "Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)",
    "context": {
        "host": "34.235.155.83",
        "user_id": 5,
        "path": "/welcome",
        "method": "GET"
    },
    "http_response_sent": {
        "status": 200,
        "duration_ms": 79.0,
        "view_ms": 78.8,
        "active_record_ms": 0.0
    }
}
```

Representing the log in JSON format provides so many benefits:

1. No special parsing rules are required to use this data in meaningful ways. Any consumer can begin using this data.
2. The format follows an official encoding format \(JSON\).
3. For interfaces designed for humans, they can simply display the `"message` key and hide the other metadata, making the log easy to ready without sacrificing the metadata.

So how did we come up with the structure above? Why did we add a `"context"` key? And why did we nest the log event attributes under `"http_response_sent"`? We'll explain these in the following sections...

## Namespace Your Events

In the example above, you'll notice we namespace our HTTP response event with a `"http_response_sent"` root key. This creates a dedicated namespace for this event, preventing type conflicts from other events with similar key names. For example, if another event used the `"status"` key, but included a string value, this would create a type conflict since our event uses an integer value. Timber allows [up to 1000 fields](../under-the-hood/schema-maintenance.md#limitations), which gives you plenty of room for all events and keys

## Naming Your Events

Creating a consistent naming scheme for your events is important since it makes understanding the resulting schema much easier. We highly recommend adopting the past-tense verb naming schema. Instead of `http_response` use `http_response_sent` . This is more descriptive of the fact that the data represents an immutable event that occurred in the past. Some other examples for clarity:

* `order_placed`
* `order_updated`
* `order_canceled`
* `sql_query_executed`
* `template_rendered`

## Keeping Your Schema Clean

Timber [limits](../under-the-hood/limitations.md) to number of tracked columns to 1,000. Setting this aside, having a schema with that many columns is very difficult for a human to use, so it's important to think carefully about the columns you send to Timber. We recommend the following best practices:

* Only send columns you want to search [search](../usage/live-tailing.md) or [graph](../usage/graphing.md).
* Encode objects to JSON that are only meant to be read. For example, incoming request parameters should be encoded to JSON in a single field instead of sending them as individual fields to Timber \(all of Timber's libraries do this automatically\). This way you have the data but you don't create arbitrary columns for each parameter.

## Classifying Your Events

As you start to add events to your application you'll start to question where you draw the line. For example, let's say you have an online store application and you want to determine how many orders were placed each day. To answer this question, you could explicitly add an `order_placed` event or you could use the `http_response_sent` event with the following conditions: `method=POST path=/orders status=201`. Which one is correct? Do you log one or both? Our answer is both, here's why:

When logging events we recommend thinking about them as falling into 2 categories: operational and business:

### Operational Events

These events are for you, the developer, to understand how your system is operating. A great way to classify these events is to ask "Would my marketing team care about this event?". Examples include:

* `sql_query_executed`
* `http_response_sent`
* `exception_raised`

### Business Events

These events are for business intelligence and should be used by your sales, marketing, and executive departments. They are almost always tied to a user or account. Examples include:

* `order_placed`
* `subscription_canceled`
* `payment_received`

### Why?

Logging both business and operational events allows you to work backwards when debugging. Very often customer issues begin with a business event. For example, if a customer is complaining that their order never shipped, you could search for the `order_shipped` business event and then work backwards to your operational events to see what went wrong.

## Using Context

Context is shared structured data that is automatically merged into your logs. It represents your application's current state and allows you to relate logs. Think of it like join data for your logs. Context, is by far, the most useful thing you can do with your logs because it allows you to segment and reduce noise. Let's look at a psuedo example:

{% code-tabs %}
{% code-tabs-item title="ruby.rb" %}
```ruby
Timber.with_context(user: %{id: "abcd1234"}) do
    logger.info("First log")
    logger.info("Second log")
end
```
{% endcode-tabs-item %}
{% endcode-tabs %}

Produces the following log events:

```javascript
{"message": "First log", "context": {"user": {"id": "abcd1234"}}}
{"message": "Second log", "context": {"user": {"id": "abcd1234"}}}
```

You can see how this can be incredibly useful to capture context like [user](structured-logging-best-practices.md#tie-your-logs-to-users) or [request](structured-logging-best-practices.md#tie-your-logs-to-requests-via-the-request-id) context.

### Keep it lightweight

Context should not contain large or complex values. Limit context to small unchanging referential data, such as IDs. Use your actual log events to contain detailed complex data.

## Pro-tips

### Tie your logs to users

This is the most popular use-case for Timber's custom context. Chances are you have users, adding user context helps to relate logs to users. If you're sensitive about security and privacy, please only assign the user ID, do not include the name or email.

### Tie your logs to requests

Including request information, such as the request ID, as context is incredibly helpful since it allows you view logs for a given request.

---

## File: guides/troubleshooting-log-delivery.md

---
---

# Troubleshooting Log Delivery

If you're having trouble viewing logs within your Timber account it's most likely due to a log delivery issue. This guide will walk through common problems and how to resolve them.

## 1. Check The Timber Status Page

To rule out an issue with the Timber service, please see the [Timber status page](https://status.timber.io) to ensure that there are not any known issues.

## 2. Test The Pipes

To rule out log delivery issues we can "test the pipes" to Timber with a simple `curl` command. This proves that log delivery is possible to your account. You can test this from your local machine but you should do this on an actual host that is sending logs.

{% hint style="info" %}
Please run this command on your actual host, this ensures that the machine sending logs can properly communicate with Timber.
{% endhint %}

```bash
curl \
    --user '{{your-timber-api-key}}' \
    --request POST \
    --header "Content-Type: text/plain" \
    --data 'debug: Testing the pipes' \
    --verbose \
    https://logs.timber.io/frames
```

You should see the following response:

```text
...TLS info...

< HTTP/1.1 202 Accepted
< server: Cowboy
< date: Thu, 21 Feb 2019 20:47:39 GMT
< content-length: 13
< cache-control: max-age=0, private, must-revalidate
< x-request-id: 2m2no48ii79n4hq984h17d52
< content-type: text/plain; charset=utf-8
< Connection: Keep-Alive
< Keep-Alive: timeout=75000 max=500
< 
* Connection #0 to host logs.timber.io left intact
Accepted logs
```

If you do not receive a `202` response then there is an issue with your account or the Timber service as a whole. You can refer to the [response codes documentation](../setup/protocols/http/#expected-response-codes) for explanation on each code. Although, Timber should respond with a body that describes the error.

## 3. Enable Debug Logs

Head back to your [i]()ntegration's page, at the bottom of every page is a "Troubleshooting" section that walks through enabling debug logs for that specific integration \(if possible\). For example, the [Elixir integration](../setup/languages/elixir/) has a [Troubleshooting section](../setup/languages/elixir/#troubleshooting) at the bottom.

## 4. Contact Support

If nothing shows up during this process, or you found an issue, please contact support.

---

## File: setup/protocols/http/README.md

---
---

# HTTP

Timber has a rich [HTTP API](http://docs.api.timber.io/) that you can use to send logs to the Timber platform.

{% hint style="info" %}
Timber offers [language level libraries](../../languages/) and support for [log forwarders](../../log-forwarders/) that handle the efficient and reliable delivery of your log data. We _highly_ recommend using those when possible.
{% endhint %}

## Installation

Forwarding logs to Timber is highly specific to your HTTP client. Below are a few examples, as well as best practices. If possible, we recommend following our [language](../../languages/), [log forwarder](../../log-forwarders/), [operating system](../../operating-systems/), or [platform](../../platforms/) integrations, as log delivery is handled for you in all of these.

### Examples

{% tabs %}
{% tab title="http \(bearer auth\)" %}
```bash
POST https://logs.timber.io/sources/YOUR_SOURCE_ID/frames
Authorization: Bearer YOUR_API_KEY
Content-Type: application/ndjson
{"level": "debug", "message": "Testing the pipes"}
{"level": "debug", "message": "Testing the pipes again"}
```
{% endtab %}

{% tab title="http \(basic auth\)" %}
```bash
POST https://user:YOUR_API_KEY@logs.timber.io/sources/YOUR_SOURCE_ID/frames
Content-Type: application/ndjson
{"level": "debug", "message": "Testing the pipes"}
{"level": "debug", "message": "Testing the pipes again"}
```

{% hint style="info" %}
Timber will discard the `user` value. Basic auth required this. Use any value you'd like.
{% endhint %}
{% endtab %}

{% tab title="curl \(bearer auth\)" %}
```bash
curl \
--request POST \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header "Content-Type: application/ndjson" \
--data '{"level": "debug", "message": "Testing the pipes"}
{"level": "debug", "message": "Testing the pipes again"}' \
https://logs.timber.io/sources/YOUR_SOURCE_ID/frames
```
{% endtab %}

{% tab title="curl \(basic auth\)" %}
```bash
curl \
--request POST \
--user "user:YOUR_API_KEY" \
--header "Content-Type: application/ndjson" \
--data '{"level": "debug", "message": "Testing the pipes"}
{"level": "debug", "message": "Testing the pipes again"}' \
https://logs.timber.io/sources/YOUR_SOURCE_ID/frames
```

{% hint style="info" %}
Timber will discard the `user` value. Basic auth required this. Use any value you'd like.
{% endhint %}
{% endtab %}
{% endtabs %}

### Getting Your API Key And Source ID

If you haven't already, please create a Timber source by following the [Sending Logs guide](../../../guides/sending-logs-to-timber.md). Timber will display your API key and source ID immediately after you create a source.

### Authorization

Timber requires the `Authorization` header as part of making requests to the Timber API. We support 2 strategies, the [`Bearer`](https://tools.ietf.org/html/rfc6750) and [`Basic`](https://tools.ietf.org/html/rfc7617) strategies.

#### Bearer Strategy

When choosing the `Bearer` strategy you can simply paste in your API key in its original form. You do not need to base 64 encode the key!

```text
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5c...
```

#### Basic Strategy

When choosing the `Basic` strategy you _must_ do 2 things:

1. Prefix your API key with a `user:`
2. Base 64 encode it.

Basic auth requires a user, any value you put as the user will be discarded by Timber, but you must supply some value.

For example, given this API key / user combination: `user:eyJhbGciOiJIUzI1NiIsInR5c`, you would supply the following header:

```text
Authorization: Basic dXNlcjpleUpoYkdjaU9pSklVekkxTmlJc0luUjVj
```

### Buffering & Batching

Always buffer and batch your log data to Timber. Do _not_ send lines individually as this is extremely inefficient; you'll quickly tax your application. Timber recommends flushing your buffer every 2 seconds or until it's size reaches 950kb. Timber will not accept requests larger than 1mb.

### Accepted Content Types

Timber accepts the following content types \(ordered by preference\):

1. \`\`[`application/msgpack`](https://msgpack.org/index.html) 
2. \`\`[`application/ndjson`](http://ndjson.org/)\`\`
3. \`\`[`application/json`](https://www.json.org/) 
4. \`\`[`text/plain`](https://www.w3.org/Protocols/rfc1341/7_1_Text.html) 
5. \`\`[`application/logplex-1`](https://github.com/heroku/logplex/blob/master/doc/README.http_drains.md#logplex-http-drains)1

### Expected Response Codes

1. `202` - Success, logs accepted.
2. `400` - Request invalid, usually due to a bad `content-type`.
3. `401` - API key invalid.
4. `402` - Subscription blocked or unpaid. Please update your subscription.
5. `500` - Timber service error.

### Timber Libraries

If you don't want to do this yourself you can use one of [Timber's language libraries](../../languages/).

## Limitations

See the [Limitations document](../../../under-the-hood/limitations.md) for a comprehensive list.

## Troubleshooting

To begin, please see our [log delivery troubleshooting guide](../../../guides/troubleshooting-log-delivery.md). This covers the most common issues we see with log delivery:

{% page-ref page="../../../guides/troubleshooting-log-delivery.md" %}

If the above guide does not resolve your issue please contact support.