> ## Documentation Index
> Fetch the complete documentation index at: https://arize-ax.mintlify.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# The arize.otel Helpers

> The arize-otel SDK collapses raw OpenTelemetry setup into a single register() call, with helpers for multi-project routing via register_with_routing and set_routing_context.

The previous four pages — [Resource](/ax/concepts/otel-openinference/resource), [Exporter](/ax/concepts/otel-openinference/exporter), [Span Processor](/ax/concepts/otel-openinference/span-processor), and [Tracer Provider](/ax/concepts/otel-openinference/tracer-provider) — walked through the OpenTelemetry tracing components one by one. Wiring them up by hand in every application is verbose. The `arize.otel` SDK collapses all of it into a single function call — and adds a few OpenInference-specific capabilities on top.

For the practical how-to of installing and using these helpers, see [Set up tracing](/ax/instrument/set-up-tracing). This page covers what they do under the hood.

# Appreciate the Simplicity

Configuring tracing with raw OpenTelemetry — Resource, Exporter, Span Processor, Tracer Provider — looks like this:

```python theme={null}
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.resources import Resource
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

def init_arize_tracing():
    resource = Resource.create({
        "openinference.project.name": ARIZE_PROJECT_NAME,
    })
    otlp_exporter = OTLPSpanExporter(
        endpoint="https://otlp.arize.com/v1",
        headers={
            "space_id": ARIZE_SPACE_ID,
            "api_key": ARIZE_API_KEY,
        },
    )
    span_processor = BatchSpanProcessor(otlp_exporter)

    tracer_provider = TracerProvider(resource=resource)
    tracer_provider.add_span_processor(span_processor)
    trace.set_tracer_provider(tracer_provider)

    return tracer_provider.get_tracer(ARIZE_PROJECT_NAME)
```

The Arize AX `register()` helper replaces all of that:

```python theme={null}
from arize.otel import register

tracer_provider = register(
    space_id=ARIZE_SPACE_ID,
    api_key=ARIZE_API_KEY,
    project_name=ARIZE_PROJECT_NAME,
)
```

Same outcome — Resource, Exporter, Span Processor, Tracer Provider all wired up — in much less code.

# What `register()` Does Under the Hood

The convenience function handles four things for you. Each one has additional capabilities specific to OpenInference and Arize AX compared to the standard OTel SDK:

| Component returned by `register()` | What it adds beyond standard OTel                                                                                                                                                                                                                                                                                                                          |
| :--------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tracer Provider**                | Returns a provider that hands out **OITracer** instances — a subclass of the OTel Tracer that reads OpenInference attributes from the OTel context. This is what makes the [OpenInference context managers](/ax/concepts/otel-openinference/context-managers) (`using_session`, `using_user`, `using_metadata`, etc.) actually attach attributes to spans. |
| **Span Processor**                 | Configured and pre-attached, ready to forward spans to the Arize AX–specific exporter.                                                                                                                                                                                                                                                                     |
| **Span Exporter**                  | Adds the headers needed to authenticate against the Arize AX collector and handles gRPC/HTTP transport correctly for your endpoint.                                                                                                                                                                                                                        |
| **Resource**                       | Sets the project name automatically from your `project_name` argument.                                                                                                                                                                                                                                                                                     |

For the canonical reference of every option, see [Configure your tracer](/ax/instrument/configure-your-tracer).

# ArizeRoutingProcessor and Multi-Project Routing

Setting the project name at the [Resource](/ax/concepts/otel-openinference/resource) level means all traces from one application go to the same Arize AX project. That's the right default for most apps.

But more complex use cases need to send traces to different projects (or different Arize AX spaces entirely) based on span attributes or request metadata — for example, a multi-tenant app that wants each customer's traces to land in their own project.

The previous workarounds were:

1. Spin up multiple Tracer Providers — but only one can be the global, so this gets awkward.
2. Modify resource attributes at the Collector level with a transform processor — works, but adds operational complexity.

Arize added a cleaner path: **`ArizeRoutingProcessor`** plus the `register_with_routing` and `set_routing_context` helpers.

## How Routing Works

Arize AX supports overriding the resource-level project name with a **span attribute** — `arize.project.name`. The `ArizeRoutingProcessor` also supports routing across Arize AX spaces via the `arize.space_id` span attribute.

`set_routing_context` is a context manager that attaches both attributes to the OTel context, so you don't have to set them manually on every span.

## Configuring Routing

```python theme={null}
from arize.otel import register_with_routing, set_routing_context

tracer_provider = register_with_routing(api_key="ARIZE_API_KEY")
tracer = tracer_provider.get_tracer(__name__)

with set_routing_context(space_id="SPACE_ID", project_name="PROJECT_NAME"):
    with tracer.start_as_current_span("Root Span") as span:
        span.set_attributes({"input.value": "..."})
```

Every span created inside the `set_routing_context` block is routed to the specified space and project.

<Info>
  `register_with_routing` uses `ARIZE_API_KEY` from the environment if `api_key` isn't passed. Both `space_id` and `project_name` must be set inside `set_routing_context` — otherwise routing won't be applied.

  **Python-only today.** For JS/TS or Go apps — or routing logic the SDK can't express — route at the [OTel Collector](/ax/concepts/otel-openinference/otel-collector) layer instead.
</Info>

For the practical setup, see [Route Spans to Multiple Projects](/ax/instrument/configure-your-tracer#route-spans-to-multiple-projects).

# When to Use Which

| Use case                                                     | Recommended approach                                                                            |
| :----------------------------------------------------------- | :---------------------------------------------------------------------------------------------- |
| Single project, simple app                                   | `register(...)`                                                                                 |
| Multiple projects from one app, per-request routing          | `register_with_routing(...)` + `set_routing_context(...)`                                       |
| Routing across many spaces in a shared-collector environment | OTel Collector with dynamic routing — see [Advanced Patterns](/ax/instrument/advanced-patterns) |
| Maximum control, custom processor pipeline                   | Raw OTel — see [Configure your tracer](/ax/instrument/configure-your-tracer)                    |

***

## Next step

You've covered every component on the OTel side. Time to learn what OpenInference adds on top — starting with the semantic conventions that make AI traces meaningful:

<Card title="Next: OpenInference Semantic Conventions" icon="arrow-right" href="/ax/concepts/otel-openinference/semantic-conventions" />
