---
title: Datadog OTLP Logs Intake Endpoint
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > OpenTelemetry in Datadog > Send OpenTelemetry Data to Datadog > Datadog
  OTLP Intake Endpoint > Datadog OTLP Logs Intake Endpoint
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Datadog OTLP Logs Intake Endpoint

## Overview{% #overview %}

Datadog's OpenTelemetry Protocol (OTLP) logs intake API endpoint allows applications, managed platforms, and OpenTelemetry Collectors to send logs to Datadog over OTLP HTTP.

Use the direct configuration on this page when you need to send logs without the [Datadog Agent](https://docs.datadoghq.com/opentelemetry/otlp_ingest_in_the_agent.md) or an OpenTelemetry Collector. For production Collector deployments, use [Set Up the OpenTelemetry Collector](https://docs.datadoghq.com/opentelemetry/collector_exporter.md).

{% alert level="info" %}
If you are sending logs from a managed platform (Cloudflare, Vercel, Heroku, and others), see [Managed platforms](https://docs.datadoghq.com/opentelemetry/setup/otlp_ingest/managed_platforms.md) for the correct endpoint configuration.
{% /alert %}

## Configuration{% #configuration %}

To send OTLP data to the Datadog OTLP logs intake endpoint, you must configure the OTLP HTTP Protobuf exporter. The process differs depending on whether you are using automatic or manual instrumentation for OpenTelemetry.

{% alert level="info" %}
Based on your [Datadog site](https://docs.datadoghq.com/getting_started/site.md), which is <YOUR_DATADOG_DATACENTER>: Replace `${YOUR_ENDPOINT}` with <YOUR_OTLP_LOGS_ENDPOINT> in the following examples.
{% /alert %}

#### Automatic instrumentation{% #automatic-instrumentation %}

If you are using [OpenTelemetry automatic instrumentation](https://opentelemetry.io/docs/specs/otel/glossary/#automatic-instrumentation), set the following environment variables:

```shell
export OTEL_EXPORTER_OTLP_LOGS_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="${YOUR_ENDPOINT}" // Replace this with the correct endpoint
export OTEL_EXPORTER_OTLP_LOGS_HEADERS="dd-api-key=${DD_API_KEY}"
```

#### Manual instrumentation{% #manual-instrumentation %}

If you are using manual instrumentation with OpenTelemetry SDKs, configure the OTLP HTTP Protobuf exporter programmatically using the following examples.

{% alert level="info" %}
OpenTelemetry SDK logs support for JavaScript and Python is in development. For the latest statuses, see [OpenTelemetry Status and Releases](https://opentelemetry.io/docs/languages/#status-and-releases).
{% /alert %}

{% tab title="Java" %}
The Java exporter is `OtlpHttpLogRecordExporter`. To configure the exporter, use the following code snippet:

```java
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;

OtlpHttpLogRecordExporter exporter = OtlpHttpLogRecordExporter.builder()
    .setEndpoint("${YOUR_ENDPOINT}") // Replace this with the correct endpoint
    .addHeader("dd-api-key", System.getenv("DD_API_KEY"))
    .build();
```

{% /tab %}

{% tab title="Go" %}
The Go exporter is `otlploghttp`. To configure the exporter, use the following code snippet:

```go
import "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"

logExporter, err := otlploghttp.New(
    ctx,
    otlploghttp.WithEndpointURL("${YOUR_ENDPOINT}"), // Replace this with the correct endpoint, minus the URL path
    otlploghttp.WithURLPath("/v1/logs"),
    otlploghttp.WithHeaders(
        map[string]string{
            "dd-api-key": os.Getenv("DD_API_KEY"),
        }),
)
```

{% /tab %}

## OpenTelemetry Collector{% #opentelemetry-collector %}

If your OpenTelemetry Collector distribution does not include all the components used by Datadog's recommended Collector setup, configure the OTLP HTTP exporter in your own distribution:

These examples use component identifiers from OpenTelemetry Collector Contrib v0.154.0. For other versions or distributions, use the identifiers that distribution supports.

```yaml
receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318

exporters:
  otlp_http:
    logs_endpoint: <YOUR_OTLP_LOGS_ENDPOINT>
    headers:
      dd-api-key: ${env:DD_API_KEY}

service:
  pipelines:
    logs:
      receivers: [otlp]
      exporters: [otlp_http]
```

Add any receivers and processors required by your Collector distribution.

For a production deployment using OpenTelemetry Collector Contrib, use the [recommended OpenTelemetry Collector setup](https://docs.datadoghq.com/opentelemetry/collector_exporter.md). It also configures sending-queue batching, resource detection, and host metadata enrichment.

## Configure log processing (optional){% #configure-log-processing-optional %}

Use the `dd-otel-log-config` header to configure how Datadog processes OTLP log records on intake. The header value is a JSON object with the following fields:

{% dl %}

{% dt %}
`keep_raw_message`
{% /dt %}

{% dd %}
**Type**: Boolean **Default**: `false` **Description**: By default, Datadog parses a JSON log body into log attributes so that you can search individual fields (for example, `@key:value`) instead of running a full-text search on the message. If `keep_raw_message` is set to `true`, Datadog does not parse the body and keeps it as a string in the `message` attribute. Use this option if you do custom parsing of the log message in a logs pipeline or if fields in your JSON body conflict with existing log attributes.
{% /dd %}

{% /dl %}

For example, to keep JSON log bodies as raw strings:

```json
{
  "keep_raw_message": true
}
```

Set the header on your OTLP requests alongside `dd-api-key`. For example, with automatic instrumentation:

```shell
export OTEL_EXPORTER_OTLP_LOGS_HEADERS="dd-api-key=${DD_API_KEY},dd-otel-log-config={\"keep_raw_message\":true}"
```

For manual instrumentation, add the header in your exporter configuration. For example, in Java:

```java
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;

OtlpHttpLogRecordExporter exporter = OtlpHttpLogRecordExporter.builder()
    .setEndpoint("${YOUR_ENDPOINT}")
    .addHeader("dd-api-key", System.getenv("DD_API_KEY"))
    .addHeader("dd-otel-log-config", "{\"keep_raw_message\": true}")
    .build();
```

In an OpenTelemetry Collector, add the header under the `otlp_http` exporter's `headers`:

```yaml
exporters:
  otlp_http:
    logs_endpoint: <YOUR_OTLP_LOGS_ENDPOINT>
    headers:
      dd-api-key: ${env:DD_API_KEY}
      dd-otel-log-config: '{"keep_raw_message": true}'
```

## Troubleshooting{% #troubleshooting %}

### Error: 403 Forbidden{% #error-403-forbidden %}

If you receive a `403 Forbidden` error when sending logs to the Datadog OTLP logs intake endpoint, it indicates one potential issue:

- The endpoint URL is incorrect for your organization.**Solution**: Use the correct endpoint URL for your organization. Your site is <YOUR_DATADOG_DATACENTER>, so you need to use the <YOUR_OTLP_LOGS_ENDPOINT> endpoint.

## Further reading{% #further-reading %}

Additional helpful documentation, links, and articles:

- [General OpenTelemetry SDK Configuration](https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/)
- [OpenTelemetry Environment Variable Spec](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/)
- [OpenTelemetry Protocol Exporter](https://opentelemetry.io/docs/reference/specification/protocol/exporter/)
